J2ME Devopment

Here are some tips and pointers for using JavaMappy in a J2ME environment.

J2ME Development with Maven2

Essentially, all your J2ME deployment woes with .jar and .jad generation can be sent sprawling into the cosmos with: com.pyx4me.j2me-maven-plugin

With a miniscule amount of POM configuration, this plugin generates and optimises all your J2ME .jars and .jads and doesn't even need the WTK installed!

Like, WOW!

To install JavaMappy into your local Maven repository, execute the following command:

mvn install:install-file \
    -Dfile=javamappy-framework-2.2.10.jar \
    -DgroupId=com.alienfactory.javamappy \
    -DartifactId=javamappy-framework \
    -Dversion=2.2.10 \
    -Dpackaging=jar \ 
    -DcreateChecksum=true

But if you want to know some specifics or like doing stuff by hand, then read on...

JavaMappy Deployment

When deploying to a J2ME environment you need to delete all non J2ME classes from the JavaMappy .jar for it to pass pre-verification. The offending classes are:

  • com.alienfactory.javamappy.viewer.render.JDKRenderer
  • com.alienfactory.javamappy.viewer.render.JDK11Renderer
  • com.alienfactory.javamappy.viewer.render.JDK12Renderer
  • com.alienfactory.javamappy.viewer.render.J2SE14Renderer

You also need to delete the following if not targeting a Nokia phone:

  • com.alienfactory.javamappy.viewer.render.NokiaRenderer

And these if your device is not MIDP 2.0 compatible:

  • com.alienfactory.javamappy.viewer.TiledLayerWrapper
  • com.alienfactory.javamappy.viewer.render.MIDP20Renderer

As far as code compilation goes, it doesn't matter if these classes exists or not. JavaMappy doesn't reference them internally so it doesn't complain if they are not there.

TIP: If you are using ProGuard, it can remove these classes for you automatically as part of its optimisation process.

JavaMappy Speed

As a rule of thumb, drawing fewer, but larger, graphical images to the screen is quicker than drawing many, smaller ones. Moreover, each time you double the block size you make 4 times less calls to the Renderer. Because of this, it is recommended you use block sizes of no less than 32x32 pixels.

If deploying to a Nokia phone, try to use the MIDP10Renderer, and NOT the NokiaRenderer, as the MIDP10Renderer can be up to 5 times faster! Strange but true. See Renderer Benchmarks below for details.

In general, try to use opaque blocks in your image tile set as transparent blocks usually make more work for the processor and slow down rendering time.

Use ProGuard to optomise your byte code.

JavaMappy .jar Size

If you are concerned that your mobile application is too big, try a few of these tips:

Save your .FMP map out as a .FMA [Mappy -> Map Tools -> Useful Functions -> Save FMP without graphics (.FMA)] and your graphics out as a .PNG. Then use these files to initialise your Renderer rather than the .FMP. Taking the J2ME example as an example:

  • AlienEpidemicJ2me.FMP = 33 Kb
  • AlienEpidemicJ2me.FMA = 3 Kb
  • AlienEpidemic.PNG = 6 Kb

Gives us a total saving of (33 Kb - 3 Kb - 6 Kb) = 27 Kb!

By default JavaMappy is compiled along with all its debug information; line numbers, private method names, etc. (Very handy for tracking down bugs.) But if you recompile the JavaMappy source code with debug information turned off you can expect to reduce the .jar size by about 10 Kb.

Use ProGuard to remove unused classes and methods from your byte code.

ProGuard

Use ProGuard (http://proguard.sourceforge.net/) a free Java class file shrinker, optimiser, and obfuscater.

ProGuard can detect and remove unused classes, fields, methods, and attributes. It can then optimise byte code and remove unused instructions. Finally, it can rename the remaining classes, fields, and methods using short meaningless names. The resulting jars are smaller and harder to reverse-engineer.

ProGuard

In addition to its standard use, try adding the following to your ProGuard configuration file:

-assumenosideeffects public class com.alienfactory.javamappy.util.** {
    <methods>;
}

This will remove most (but not quite all) calls and references to the Logger and ParameterChecker classes. Both of which your application can probably run without.

Renderer Benchmarks

The J2ME example was modified so it rendered 100 frames non stop with a given renderer. The following values were recorded from a Nokia N-Gage using JavaMappy 2.2.4:

Init Mem:
How much memory it took to store the tile map image.
Init Time:
How long it took to initialise the renderer.
Game Time:
How long it took to render 100 frames.
Game fps:
Frames per Second, i.e. 100 frames / Game Time.

The results are given below:

 Init Mem (bytes)Init Time (seconds)Game Time (seconds)Game fps
 
MIDP 1.0 FMP Renderer72,37210.953 5.26619.0
72,00810.641 5.21919.2
 
MIDP 1.0 FMA Renderer
with opaque .png image
67,688 5.125 3.03133.0
67,680 5.250 3.01633.2
 
MIDP 1.0 FMA Renderer
with transparent .png image
67,688 5.125 5.51518.1
67,692 5.297 5.51618.1
 
Nokia FMP Renderer72,136 4.59314.953 6.7
72,136 4.57914.938 6.7
 
Nokia FMA Renderer
with opaque .png image
67,660 5.01514.453 6.9
67,680 5.07514.342 7.0

The clear winner is the MIDP 1.0 FMA Renderer using the MIDP10Renderer(Map, String, boolean) constructor. It also seems that you can decrease your rendering time dramatically by using as few transparent tiles as possible.