It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.


Resource Guide

Creating Games using J2ME

The Good News
First, some very good news: Java-enabled mobile phones embed the KVM right on the chipset. That means there are no memory hits, quick startup times, and quicker processing times.
Another interesting development is that several brands of Java phones offer neat extension APIs that let you access special, native features. Motorola and Nokia, for example, have announced game APIs that allow for audio, animations, transparency, and better graphics.
Additionally, 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.

Writing a native handheld application requires countless hours of debugging, emulating, testing, deploying, redebugging, and packaging. Write to a wrong memory location, and you can easily fry the machine. Waste a little memory on a desktop or server application, and nobody will bat an eye. But when dealing with a tiny space like the Palm, every bad byte hurts. Memory leaks in Java are possible, but they are much easier to avoid.

Perhaps the most compelling argument for using Java is that - you guessed it - you can write once and run every-damn-where. 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!

Creating a Midlet


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

  1. Write your program
  2. Compile it
  3. Preverify it
  4. Package It
  5. Test It
  6. Debug It
  7. Release it!

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 on the Palm will happen much more quickly, saving you valuable startup time.

There are many development environments that do all the compiling, preverification, and packaging for you. Metrowerk's Code Warrior has a J2ME plug-in, and Borland's JBuilder has a Handheld Express add-on. In addition, Nokia, Siemens, RIM, Zucotto, and Motorola all offer special SDKs and IDEs for J2ME development. See the resources list at the end of this article for more info.

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.

Sun's own J2ME Wireless Toolkit is free, complete, really easy, and available for Windows, Linux, and Solaris.

We'll be using the Wireless Toolkit throughout this article.

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

Write Your Program

Just like an applet is based on the java.applet.Applet calss, 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.

Enough talk. Let's look at some code. Let's pass up the wonderful cliché of a nice Hello World program and create a full single-player Tic-Tac-Toe game instead.

Writing the Midlet

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 a 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 or other devices is a Display object. Every MIDlet has one and only one Display object, which you can access using getDisplay(this).

The Display
A Display can consist of either a Screen object or a Canvas. Every Screen has an optional title (usually at the top) and Ticker (usually running along the bottom). Specific types of Screens include:

  • List: A row of elements that a user may choose from, perfect for a menu.
  • Alert: A "dialog box" that appears and shows some text and/or an Image to the user and then, after a set amount of time, disappears. This is perfect for important messages.
  • Form: A screen for user input which may contain all or some of the following MIDP objects: ImageItem, StringItem, TextField, DateField, Gauge, or ChoiceGroup. A ChoiceGroup is equivalent to radio buttons or check boxes.
  • TextBox: A box that allows the user to type in or edit some text.
    Using the ease and convenience of Screens, creating quick MIDlets is a snap.
Getting Graphical

But let's get real, here. Most game developers want to customize components, capture user input, and create more detailed graphics. So pretty much every game will need something called a Canvas.

A Canvas must define the paint() method. The Graphics object allows for simple renderings using familiar Java methods such as drawArc(), drawImage(), drawLine(), drawRect(), drawString(), fillRect().

Note that images need to be in the PNG format, and color images are supported on phones that have color screens. You could create an image as follows:

Image house = Image.createImage("/house.png");

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

class SillyCanvas extends Canvas
{
     public void paint(Graphics g)
     {
        g.drawRect(1,1,getWidth()-2,getHeight()-2);
        g.setFont(Font.getFont(Font.FACE_MONOSPACE,
           Font.STYLE_PLAIN,Font.SIZE_SMALL));
        g.setColor(0);
        g.drawString("Hello World", getWidth() / 2, 0,
           Graphics.HCENTER | Graphics.TOP);
        g.drawImage(house, 10,30, g.TOP|g.LEFT);
     }
}

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

private SillyCanvas aCanvas = new SillyCanvas();

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:

theDisplay.setCurrent(aCanvas);

Note that 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.

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 sleep() method within an endless loop to achieve slower or faster frame rates.
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 are common... if you're lucky.

________________________________________________________

Creating Tic Tac Toe


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service