Downloads Articles Devices Publishing News & Info Developer Discussions Sign In

Articles
Perspective Articles
Tech Talk
Interviews

Related Content
Articles
  Developing Applications with the Java APIs for Bluetooth (JSR-82)
-02/23/2004
  A Review of the 5th Annual Wireless Java Conference
-01/28/2004
  J2ME Game Optimization Secrets
-01/09/2004
  Multi-Player MIDP Game Programming
-11/05/2003
Downloads
  Piranha Pricecheck
-08/07/2003
  Akalabeth
-08/06/2003
  BallGames
-08/06/2003
  MEJ2METask
-08/06/2003
FAQ
  How do I debug on an actual device (i85s/i50sx)?
-10/13/2001
  How do I obfuscate using RetroGuard?
-10/01/2001
  How can I find out when the value in the TextField has been changed?
-07/24/2001
  How do I create a button on my Palm using MIDP?
-07/24/2001







MIDP 2.0 Games: a Step-by-Step Tutorial with Code Samples

by Carol Hamer
-09/10/2003

[page 2][page 3][page 4][page 5][page 6]

Writing games for small devices is easy and fun with the new MIDP 2.0 API. The biggest difference for the game developer between MIDP 1.0 and MIDP 2.0 is enhanced graphics capabilities. With MIDP 1.0 you can certainly write some fun games--those of us who remember the Atari 2600 will remember that the games were fun even if they weren't always beautiful. The 2.0 version of the Mobile Information Device Profile doesn't bring us quite to the level of the latest game cube, but it brings your cell phone at least to the realm of Super Mario Brothers or thereabouts.

In this tutorial I will go over the steps involved in writing a simple game MIDlet. (A MIDlet is like an applet except that it runs on a mobile device rather than in a browser.) I will assume that you know some Java but that you're new to J2ME. My example is a game involving a cowboy walking through a prairie jumping over tumbleweeds. It's kind of a silly game, but it illustrates most of the basics that you'll need when writing more reasonable games.

All of the source code and resources for this example can be found here.

Getting Started

If you haven't already downloaded and installed J2ME, you can get it at http://java.sun.com/j2me/download.html. The Java 2 Micro Edition Wireless Toolkit contains a MIDlet development environment, a cell-phone emulator, and a number of helpful demo applications with source code. I'm not going to go into too much detail here about the installation since it varies from system to system and the documentation bundled with the download is reasonably clear.

When you examine the demo applications, you'll notice that they consist of a jar file and a jad file. The jar file contains the class files, the resources, and a manifest file. The jad file contains approximately the same descriptive information with the addition of two items that help the device load the MIDlets: the size and the URL of the MIDlet jar. Here is an example of the jad file I used for my Hello World application:

MIDlet-1: Hello World, /icons/hello.png, net.frog_parrot.hello.Hello
MMIDlet-Description: Hello World for MIDP
MIDlet-Jar-URL: hello.jar
MIDlet-Name: Hello World
MIDlet-Permissions: 
MIDlet-Vendor: frog-parrot.net
MIDlet-Version: 2.0
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-2.0
MIDlet-Jar-Size: 3201

The MIDlet-1 (and MIDlet-2, etc.) property gives the name of the MIDlet, the location of the MIDlet's icon, and the MIDlet class to run. The first two items describe how the MIDlet will appear on the menu of MIDlets. The icon should be in the jar file, and its location should be given in the same format as is used by the method Class.getResource(). Thus in this example your jar file should contain a top level folder called icons which contains an icon called hello.png which looks like this:

The MIDlet-Jar-Size property gives the size of the corresponding jar file in bytes which you can find by looking at the properties or long listing of the jar file. Be aware that if you rebuild the demos or your own applications using the build script bundled with the toolkit, you must manually update the size of the jar file in the jad file. If the MIDlet-Jar-Size property in the jad file does not match the size of the jar file, the MIDlet will not run. (Since the size generally changes with every build and it's annoying to open your jad file in a text editor with every build, I've included some build script modification suggestions in Appendix A at the end of this article.) The MIDlet-Jar-URL property gives the address of the MIDlet jar relative to the location of the jad file. If the jar file and the jad file are kept in the same directory, this is just the name of the jar file. The other properties are self-explanatory.

Hello World

To illustrate the components of a very basic MIDlet I've written a version of the classic "Hello World" application. The MIDlet will display the message "Hello World!" on the screen and remove it (or later put it back) when the "Toggle Msg" button is pressed. The "Exit" button will terminate the MIDlet. The application consists of two classes: the MIDlet class called Hello and the Canvas class called HelloCanvas. How it works is sufficiently simple that I will leave the explanations of the various steps in the comments.

Here's the code for Hello.java:

package net.frog_parrot.hello;

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

/**
 * This is the main class of the hello world demo.
 *
 * @author Carol Hamer
 */
public class Hello extends MIDlet implements CommandListener {

  /**
   * The canvas is the region of the screen that has been allotted 
   * to the game.
   */
  HelloCanvas myCanvas;

  /**
   * The Command objects appear as buttons.
   */
  private Command exitCommand = new Command("Exit", Command.EXIT, 99);

  /**
   * The Command objects appear as buttons.
   */
  private Command newCommand = new Command("Toggle Msg", Command.SCREEN, 1);

  /**
   * Initialize the canvas and the commands.
   */
  public Hello() {
    myCanvas = new HelloCanvas(Display.getDisplay(this));
    myCanvas.addCommand(exitCommand);
    myCanvas.addCommand(newCommand);
    myCanvas.setCommandListener(this);
  }

  //----------------------------------------------------------------
  //  implementation of MIDlet

  /**
   * Start the application.
   */
  public void startApp() throws MIDletStateChangeException {
    myCanvas.start();
  }
  
  /**
   * If the MIDlet was using resources, it should release 
   * them in this method.
   */
  public void destroyApp(boolean unconditional) 
      throws MIDletStateChangeException {
  }

  /**
   * This method is called to notify the MIDlet to enter a paused 
   * state.  The MIDlet should use this opportunity to release 
   * shared resources.
   */
  public void pauseApp() {
  }

  //----------------------------------------------------------------
  //  implementation of CommandListener

  /*
   * Respond to a command issued on the Canvas.
   * (either reset or exit).
   */
  public void commandAction(Command c, Displayable s) {
    if(c == newCommand) {
      myCanvas.newHello();
    } else if(c == exitCommand) {
      try {
 destroyApp(false);
 notifyDestroyed();
      } catch (MIDletStateChangeException ex) {
      }
    }
  }
  
}

Here's the code for HelloCanvas.java:

package net.frog_parrot.hello;

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

/**
 * This class represents the region of the screen that has been allotted 
 * to the game.
 * 
 * @author Carol Hamer
 */
public class HelloCanvas extends javax.microedition.lcdui.game.GameCanvas {

  //---------------------------------------------------------
  //   fields

  /**
   * A handle to the screen of the device.
   */
  Display myDisplay;

  /**
   * whether or not the screen should currently display the 
   * "hello world" message.
   */
  boolean mySayHello = true;

  //-----------------------------------------------------
  //    initialization and game state changes

  /**
   * Constructor merely sets the display.
   */
  public HelloCanvas(Display d) {
    super(false);
    myDisplay = d;
  }

  /**
   * This is called as soon as the application begins.
   */
  void start() {
    myDisplay.setCurrent(this);
    repaint();
  }

  /**
   * toggle the hello message.
   */
  void newHello() {
    mySayHello = !mySayHello;
    // paint the display
    repaint();
  }

  //-------------------------------------------------------
  //  graphics methods

  /**
   * clear the screen and display the hello world message if appropriate.
   */
  public void paint(Graphics g) {
    // x and y are the coordinates of the top corner of the 
    // game's display area:
    int x = g.getClipX();
    int y = g.getClipY();
    // w and h are the width and height of the display area:
    int w = g.getClipWidth();
    int h = g.getClipHeight();
    // clear the screen (paint it white):
    g.setColor(0xffffff);
    g.fillRect(x, y, w, h);
    // display the hello world message if appropriate:.
    if(mySayHello) {
      Font font = g.getFont();
      int fontHeight = font.getHeight();
      int fontWidth = font.stringWidth("Hello World!");
      // set the text color to red:
      g.setColor(0x00ff0000);
      g.setFont(font);
      // write the string in the center of the screen
      g.drawString("Hello World!", (w - fontWidth)/2, 
     (h - fontHeight)/2,
     g.TOP|g.LEFT);
    }
  }

}

 
1 of 6  Next >>


  about us | contact us | contribute | discussions | privacy | register | corporate
©2000-2003 Micro Developer Network Inc. All rights reserved. J2ME is a trademark of Sun Microsystems.