|
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, oreventuallyin
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:
- Write
your program
- Compile
it
- Preverify
it
- Package
It
- Test
It
- Debug
It
- Release
it!
The only
thing that should set off your mental alarms is step number threepreverification.
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.
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:
- Have
your main Canvas class draw a special offscreen image.
- 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.
- 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.
|