Table of Contents - JGame - a Java game engine for 2D games
      Running and compiling
            JRE base classes
            JRE applications
            MIDP base classes
            MIDP applications
            Javadoc
      Software development
            JRE applications
            JRE Webstart
            JRE applet
            JOGL applications
            JOGL webstart
            JOGL applet
            J2ME midlet
      Porting from one version to another
            1.x -> 2.x
            2.0 -> 2.1
            2.x -> 3.0
            3.0 -> 3.1
            3.1 -> 3.2
      Game generator
      Java 1.2

JGame - a Java game engine for 2D games

By: Boris van Schooten, schooten@cs.utwente.nl

Website: www.13thmonkey.org/~boris/jgame/

Version: 3.3, 10 mar 2008 (20080310)

JRE (personal computer) platforms:
    Java 1.2 or higher; 250Mhz+ with 2D graphics acceleration recommended
    for the example games.
Tested on: Linux, FreeBSD, NetBSD, Windows, MacOS X,
           Java 1.2.2, 1.3.1, 1.4.2, 1.5.0, 1.6.0
JOGL (opengl) platforms:
    Java 1.4 or higher; 500Mhz+ with 32Mb 3D graphics acceleration recommended
    for the example games.
Tested on: Linux, Windows, MacOS X, NetBSD
           Java 1.4.2, 1.5.0, 1.6.0
J2ME (MIDP, mobile) platforms:
    MIDP2.0/CLDC1.1
Tested on: WTK2.5.x emulator, Sagem My401C, My411X, Sony Ericsson K320i
           (I am looking for more test platforms!)

Distribution license: Revised BSD license (see LICENSE)

Description: JGame is a small 2D game engine that runs on any Java 1.2+ JRE platform, as well as the J2ME (MIDP2.0/CLDC1.1) mobile platform. It provides a very high-level framework, enabling "classic" type arcade games to be developed with a minimum of code and effort. It is based on sprites with automatic animation and collision detection, and a tile-based background with easy sprite-tile interaction facilities. Games can be run as applet or webstart, and can be scaled to any resolution, even on mobiles. OpenGL enhancements are available on 3D accelerated machines.

Features:

  • Multiplatform.
    • Tested on various platforms.
    • Can easily be run as applet, from a jar, or as a webstart.
    • Games can be run on the J2ME platform without requiring changes in the code.
    • Games can be run both with and without openGL back-end, with openGL enabling some extra graphical quality and features.
    • You can program a game at one resolution, but it can be scaled to any desired resolution when run. Scaling preferences enable precise control of scaling under J2ME.
  • Highly optimised.
    • Implementation ensures optimised and accelerated graphics for a variety of platforms without requiring extra packages; even works well on remote X11 displays.
    • Code is optimised for maximum speed and minimum object creations so it works well on slower machines such as mobiles.
  • Easy handling of sprites and animations.
    • Built-in sprite animation
    • Load sprites, tiles, and colour fonts directly from sprite sheets.
    • Define images, animations, and sounds in a text file.
  • Tile-based background handling, with decorative backdrop.
    • Scrolling using a virtual screen / viewport model
    • Built-in playfield wrap-around facility
    • multilayer parallax backdrop and zooming/rotating view in OpenGL
  • Automatic collision detection with sprites and background tiles, and easy background tile interaction.
  • Channel-based sound system with sound enable/disable built in
  • Can run at both fixed frame rate and variable (video synchronised) frame rate; built-in facilities for making variable frame rate easier to use.
  • A state machine model for in-game sequences.
  • A standard game state machine and some standard game objects are provided.
  • Standard highscore table functions are provided.
  • Debugging facilities, which include: visualising bounding boxes, printing debug messages next to an object on the playfield.
  • A web-based game generator for generating prototype games without any programming (under development).

To do / problems:

  • ensure exit dialog always on top
  • ensure taskbar does not obscure playfield
  • file a bug report for the bugs in TextRenderer, which sometimes refuses to render whitespace and sometimes garbles the result completely.
  • file bug report about crashes in glBlendFunc
  • look at possibility of non-integer scroll and drawing/sprite offsets, and compatibility between them. In JOGL, even scaled offsets may be noninteger.
  • add a flip x/y function for OpenGL images
  • add image getsize and existsImage to JGEngine interface
  • sprite textures should have transparent 1-pixel border around them, otherwise strong magnification will not look right around the borders
  • fix scrolling bug on MacOS. I found that there is something wrong with the bounds of the copied bg areas.
  • fix scaling artifacts on MacOS. I found that graphics may get scaled to the wrong background colour so you get whitish borders around graphics. This may be a Macos bug; the behaviour is not always reproducible and sometimes plain erroneous.
  • more complete MIDP support: sound, mouse, highscores, font size/style, debug facilities.
  • implement MIDP hideNotify/showNotify?
  • give error when setCanvasSettings or setScalingPreferences are set at the wrong point
  • There is no warning in dbgShowBoundingBoxes that a bbox is not defined
  • image maps are sometimes loaded every time an image is extracted? This may be caused by loadImage not loading the image into a buffered image, and the unbuffered image being uncached by the system. Check this out!
  • appletviewer may give security exceptions when loading a jar from the local filesystem
  • fix the ugly volatileimage code which doesn't work in applets by means of a conditional compile scheme
  • fix the font alignment problem which aligns vertically according to text height, making alignment dependent on the particular letters used.

To do, long term:

  • dynamic depth sorting (by depth value)
  • option to turn off automatic scaling
  • shorthands for handling sequences in the sprite table file
  • Port the gamegen concept to a more general non-PHP implementation. The basic work has been done, but is not yet presentable.
  • further extend the library of standard objects, and include them in the gamegen framework
  • animated tiles
  • add scaling to image definition operations
  • full multiple background layer support?
  • autodetect OpenGL / switch between OpenGL/AWT runtime

Running and compiling

The installation comes with pre-compiled classes and Jars. This section explains what they are and how to use them.

JRE base classes

  • jgame-jre.jar: Java 1.3 classes of JGame library (you can include the jar in your classpath)

  • jgame-jogl.jar: Java 1.4 classes of JGame, using the JOGL (OpenGL) extension (you can include the jar in your classpath)

People using Java 1.2 have to recompile the classes (see also the notes below).

If you want to use JOGL, you have to install it first. You need JOGL JSR 231. This is the new JOGL released by Sun (javax.media.opengl). There is also an older JOGL (net.java.games.jogl) which is not suitable. Download it from:

https://jogl.dev.java.net/

It has no installer. You can just put the jars in JAVA_HOME/jre/lib/ext, and the native code libraries in JAVA_HOME/jre/bin, though the README discourages this (version clashes may occur). An alternative is to set CLASSPATH to point to the Jars, and pass -Djava.library.path=<PATH_TO_NATIVE_LIBS> to pass the location of the native libraries to Java. Or:

java -cp PATH_TO_JOGL_AND_GLUEGEN_JAR -Djava.library.path=PATH_TO_NATIVE_LIBS
    YOUR_JOGL_APPLICATION

To recompile the JRE base classes and jars (without JOGL):

  ./make-base  (that will be .\make-base or just make-base on Windows)

To recompile the JRE base classes and jars with JOGL backend (you must have JOGL installed):

  ./make-base-jogl  (.\make-base-jogl or just make-base-jogl on Windows)

JRE applications

  • jgame-all.jar: all examples plus the launcher (without JOGL). Start using:

  java -jar jgame-all.jar

You can run individual examples using:

  java -classpath jgame-all.jar examples.<gameclass>

You can run the examples with OpenGL by putting the JGame-JOGL classes before the regular classes in the classpath, so that they get loaded first, like so:

  java -cp $CLASSPATH:jgame-jogl.jar:jgame-all.jar examples.Launcher  (unix)
  java -cp %CLASSPATH%;jgame-jogl.jar;jgame-all.jar examples.Launcher  (dos)

Here, we assume that you use CLASSPATH to point to the JOGL base classes. This "class overriding trick" may not work in all cases. Alternatively, you can recompile the jars for JOGL.

To recompile the JRE examples, tutorials, gamegen, and generate the example jars:

  ./make-base
  ./make-apps       (creates the JRE version)
  ./make-base-jogl
  ./make-apps-jogl  (creates the JOGL version)

Here's an overview of the individual example game classes:

x examples.nebulaalpha.NebulaAlpha - minimal game using base classes only
  examples.Insecticide     - example tile-based game using base classes only
  examples.ChainReaction   - example mouse-based game using base classes
  examples.SpaceRun        - minimal game using StdGame framework w/ defaults
  examples.SpaceRunII      - minimal game using StdGame with customisation
  examples.SpaceRunIII     - minimal game illustrating scrolling
x examples.Munchies                - example game using StdGame framework
x examples.waterworld.WaterWorld   - example game using StdGame framework
x examples.Ramjet                  - example game using StdGame framework
x examples.packetstorm.PacketStorm - example game using StdGame framework
  examples.ogrotron.Ogrotron       - example game using StdGame framework
  examples.CavernsOfFire           - example game using StdGame, scrolling
x examples.matrixminer.MatrixMiner - uses StdGame and Std... objects
  examples.PubMan                  - uses StdGame and Std... objects
  examples.DungeonsOfHack          - uses StdGame, Std... objects, scrolling
  examples.guardian.Guardian       - uses StdGame, scrolling
  examples.dingbats.Dingbats       - JOGL game

(x) - game has (some) sound

The desired screen size can be supplied as command line parameters to most of the applications. If no size is specified, full-screen is assumed. All applications can be quit by pressing Shift-Esc (this is a standard JGame feature).

  • jgame-gamegen.jar: the (web-based) game generator. For more information about this program see the subdirectory gamegen/

  • smallgames.jar: the smaller games in one jar, for running as applets.

  • nebulaalpha.jar, matrixminer.jar, waterworld.jar, packetstorm.jar, guardian.jar: the larger games come in separate packages. Start with java -jar <game>.jar

  • dingbats.jar: JOGL version of dingbats (is compiled by jgame-apps-jogl only). Can be webstarted using dingbats.jnlp.

  • html/: HTML for running the games as applets. Try:

  appletviewer html/applet-<THE_GAME>-<YOUR_RESOLUTION>.html

  • tutorial/: a tutorial in 9 simple example applications, illustrating the different features of the game engine. The code is self-documenting.

MIDP base classes

  • classes-midp/: java 1.3 classes of the JGame API for MIDP.

Note, to run a MIDP game you have to put all classes and resources in a single Jar, and provide a manifest file with the right data (see section "software development").

To recompile the MIDP base classes, you must set the WTK_HOME variable to point to your WTK install. Then you can use:

  ./make-midp-base

MIDP applications

  • <appname>Midlet.jar and .jad are the Midlet versions of some of the games.

Ensure the WTK_HOME variable points to your WTK install. To recompile the MIDP examples and generate the JARs and JADs:

  ./make-midp-spacerun
  ./make-midp-pubman
  ./make-midp-munchies
  ./make-midp-cavernsoffire
  ./make-midp-dungeonsofhack
  ./make-midp-matrixminer
  ./make-midp-ogrotron

In DOS, you have to ensure the MIDlet-Jar-Size attribute in the jad is set to the new jar size. This can be done by using the dir output found in the jad. In unix, this is done automatically.

The Jars can be shrunk by almost a factor 2 by using proguard (or another code optimiser). A script doshrinkjar.bat is provided to perform shrinking with proguard (tested with 3.9 or 4.1). Usage is:

  ./doshrinkjar [jar-to-shrink-without-file-extension] [manifest-file]

The shrunk jar is written in classes-midp-shrunk. You have to have proguard installed, and specify the path to proguard in the shell variable PROGUARD_HOME.

You can compile and shrink all midlets in one go:

  ./make-midp-apps

The shrunk midlets are compiled into classes-midp-shrunk.

You can run the midlets in the WTK emulator (called runmidlet or emulator), or download the game to your mobile. The easiest is usually downloading from the internet, but this usually costs money. Almost all mobiles also enable applications to be downloaded directly from the PC. However, in some cases this may be something of a challenge (this may involve, for example, writing the jars into a hidden directory). Some mobiles use a data cable for this, some use bluetooth or IRda to transfer files. My own mobile uses a regular USB mass storage interface. When downloading from the internet, you typically get the Jad, which then automatically starts download of the Jar. When downloading from your PC you may require either Jad+Jar or just the Jar.

Javadoc

  • javadoc/: the API documentation

To re-generate the javadocs, use:

  ./make-docs

Software development

JGame offers several platform and deployment options which are explained in this section. Basically, there is the JRE (Java Runtime Environment) platform, both with and without OpenGL (JOGL) extension, meant for regular PCs, and the J2ME (Java 2 Micro Edition), for mobiles. If you want to develop in JRE, you must get the JDK (Java Development Kit). This includes the javac compiler, the jar tool, etc. You have to install the JOGL extension separately, if you want to use it (see above). If you want to develop for J2ME, you must also get the WTK (Wireless Toolkit), which contains the J2ME base classes, an emulator, the preverify tool, etc. To run JGame, mobiles need to be CLDC1.1/MIDP2.0 capable.

Full API documentation is found in the javadoc/ directory; general documentation about game development and practical issues of working with JGame are found in the MANUAL file; a tutorial introducing the JGame features step by step by means of example code is found in the tutorial/ directory. The example games should also illustrate well how a game may be built with JGame. More general information about java, games, graphics, etc. you can find on the JGame website.

For people who want to port their JGame 1 or 2 app to JGame 3, read the section on porting below.

JRE applications

Most Java developers are particularly familiar with JRE, and starting software development should be easy. If you are new to Java, here are some suggestions. You can start writing your own JGame games by first putting the jgame package in your classpath. You can do it by adapting the CLASSPATH variable, so that it points to the JGame classes. You can either point to the JGame main directory, or point to jgame-jre.jar. For example, using BASH, stand in the JGame main directory and use:

  export CLASSPATH=$CLASSPATH:`pwd`/jgame-jre.jar
In Windows, try:
  set CLASSPATH=.;<put the path to jgame-jre.jar here>

You can also specify the classpath using the -classpath or -cp option:

  java (or javac) -classpath .:<path to jgame-jre.jar> <my classes> (unix)
  java (or javac) -classpath .;<path to jgame-jre.jar> <my classes> (dos)

Always remember to put ".", the current directory, or your project directory if not equal to the current directory, in your classpath. The examples/Std*... game object classes are included in jgame-jre, but it may be useful to copy them to your own project directory, since it's likely you're going to adapt them some in the later stages of your game project. You may want to move them to another directory in your own project; remember to change the 'package examples' lines in the java files if you do this.

JRE Webstart

You can run your application using the java command, but you can also package it into a webstart package. This enables easier installation from the web or from a shortcut, and automatically downloading updates. To be able to do this, you need to do 3 things:

  • put all your classes and media files in a single Jar, including the JGame base classes. There should be a manifest included so the application can be run with java -jar <jarfile>, such as the jgame-all.jar file.

  • sign the jar (optional). Signing the jar enables the application to have the full privileges of a regular application. If you don't sign, the application will not have certain abilities, such as loading/saving configuration or highscores. Signing can be done like this:

  keytool -genkey -validity <number of days that the generated key is valid>
  This will prompt for two passwords and some personal data.  The first
  password is the main password for the .keystore file that is generated, the
  second is the password for the generated key.  The above command generates
  the default key "mykey".  If you forgot the keystore password, simply delete
  the .keystore file and try again.  Now use:
  jarsigner <jarfile> mykey
  After typing the keystore password, the jarfile will be signed with the key
  data in mykey.  

  • create a JNLP file. This is basically a "shortcut" to the Jar file. When users click on the JNLP file (or invoke it using javaws), the Jar is downloaded and executed. The JNLP file also specifies the execution privileges. Look at jgame.jnlp and jgame-signed.jnlp to see what a JNLP looks like.

JRE applet

For running games as applets, the Java plugin that comes with the JRE is used. A HTML file specifies an <applet> tag, which may directly refer to the applet class file, or a class within a given Jar. Applets can be put on the web server both as a collection of files or in a Jar. Applets always have a fixed size within the HTML window. Parameters may be passed using <param> tags. There are many examples in the html/ and tutorial/ directories. Applets have limited privileges. In particular, they cannot access files from the local file system. Applets can be paused and unpaused by the web browser, in which case start() and stop() are called. A game may need to detect whether it is an applet. Use the isApplet() method for this. You can use the appletviewer tool to test applets without requiring a web browser.

JOGL applications

If you have JOGL installed (see section running and compiling: JRE base classes), running JOGL applications just means replacing jgame-jre.jar by jgame-jogl.jar. Another option is to define a Webstart, which also takes care of JOGL installation for you.

JOGL webstart

This works the same as with a JRE Webstart, only you have to specify the JOGL resource, which is then automatically downloaded from Sun. See jgame-jogl.jnlp to see how it's specified. Note that the main jar, tutorial-jogl.jar is just tutorial.jar compiled with make-apps-jogl.

JOGL applet

JOGL applications can even be run as applets, through a special wrapper called the JNLPAppletLauncher. See: tutorial/applet-example9-jogl.html for an example. Note that the size of the applet canvas has to be passed through the applet parameters canvaswidth / canvasheight. This is because width and height do not work as expected in an applet wrapped by the launcher. For more information about the JNLPAppletLauncher, see:

https://jogl-demos.dev.java.net/applettest.html

J2ME midlet

J2ME (aka MIDP) applications (aka midlets) are much like applets. They have a fixed screen size, and can be paused and unpaused like applets. If you want a single game to make use of both PC and mobile optimally, you typically want to set some of its parameters according to whether it's a midlet or not. Use isMidlet() to detect this. Midlets have to be compiled and packaged in a special way (see also the midp make scripts). When compiling them, you need to specify that special base classes (classes different from the JRE base classes) are to be used, and that bytecode for Java 1.3 has to be generated. Basically:

  javac -bootclasspath ${CLDCAPI}:${MIDPAPI} -source 1.3 -target 1.3 <javafiles>

Then you have to preverify the classes (basically this involves doing some of the class linking normally done at runtime but not supported by mobiles):

  ${WTK_HOME}/bin/preverify -d <dest-directory> <source-directory>

WTK_HOME points to your WTK install. This generates the preverified classes in dest-directory. Now, you can jar these plus the media files your game requires into a single jar. This jar must include a special manifest that specifies the necessary MIDlet information. Look at the manifest_midp_... files for examples. In some cases, you also need to create a "shortcut" file called a Jad. The Jad is virtually identical to the manifest file, except that it must contain a link to the Jar, and the correct size of the Jar file must be included in the MIDlet-Jar-Size attribute. The Unix make scripts update the Jar size automatically.

Since Jar size on mobiles is critical, it may be worth squeezing it to as small a size as possible. There exist Jar shrinkers which shorten symbol names, optimise bytecode, and remove unused methods (which may help a lot when you're using a generic library like JGame). I used Proguard to shrink my files (see also the section "MIDP applications"). See doshrinkjar.bat to see how this works. You have to specify the cldcapi11.jar and mdipapi20.jar as library jars, and don't forget to turn off mixed case class name generation (since midp cannot handle separate classes with only case differences, like 'a.class' and 'A.class'!). The shrunk jar has to be re-preverified.

Porting from one version to another

Throughout its lifetime, JGame has undergone several API changes that require changing older code in order to compile on the newer versions. They are listed in this section.

1.x -> 2.x

Due to the distinction between playfield and viewport, the methods for querying the screen dimensions have been renamed:

screenWidth/Height -> pfWidth/Height or viewWidth/Height

pfTileWidth/Height -> tileWidth/Height

2.0 -> 2.1

The initialisation sequence has been changed. Instead of passing the playfield dimensions to the initEngine method, the init code calls initCanvas at some later point, so that playfield dimensions can be determined after reading applet parameters. Inside initCanvas, the playfield dimensions (and scaling preferences in 3.x) can be set using setCanvasSettings (and setScalingPreferences in 3.x). The old initialisation code would be a couple of constructors like this:

public void MyGame (int w,int h) { initEngine(w,h,30,20,16,16,null,null,null); } public void MyGame () { initEngineApplet(30,20,16,16,null,null,null); }

In the new initialisation API this reads:

public void MyGame (int w,int h) { initEngine(w,h); } public void MyGame () { initEngineApplet(); }

public void initCanvas () {setCanvasSettings(30,20,16,16,null,null,null); }

2.x -> 3.0

In spite of the major structural changes in JGame3, the API changes are minor. Nevertheless, a number of things have to be changed before you can compile a JGame 1 or 2 application to JGame 3. Making the changes should usually be as easy as an couple of automatic search/replaces. These are the following:

Change all references to Point, Rectangle, Color, and Font to JGPoint, JGRectangle, JGColor, JGFont. These are platform-independent minimal versions of the AWT classes, and only have the most basic methods. This means you may have to rewrite code that refers to special methods in the AWT classes.

All references to Dimension have been replaced by JGPoint. In particular the parseSizeArgs now returns a JGPoint.

Replace any calls to setCursor(Cursor) by setMouseCursor(int) or setMouseCursor(Object). The int version is used for setting a default cursor, the latter for removing the cursor or setting your own cursor. If you want to set your own cursor, you must pass a java.awt.Cursor to setMouseCursor, which makes your application JRE-only.

After these changes, you can probably remove the java.awt.* import, because all AWT classes have been replaced. If not, then you have to remove any remaining dependencies before you can compile your application for MIDP. Note also that MIDP has only minimal implementations of the base classes, and has other limitations.

Include one extra import, jgame.platform.*, so you get:

import jgame.*; import jgame.platform.*;

To be portable to MIDP, remove or rename any game states with names other than those used in StdGame. These are "StartGame", "LevelDone", "InGame", "Title", "Highscore", "EnterHighscore", "LifeLost", "GameOver", "Paused". Because MIDP does not support reflection, the MIDP version only supports states with these names.

MIDP does not have a Math.atan2 method, but JGame now provides a replacement in JGEngine.

3.0 -> 3.1

A gamespeed variable has been introduced for making changing the game speed easier. This does mean, however, that some things, in particular the StdGame and JGTimer timers, are no longer ints but are now floats. Usually this causes no problems, but it does in some particular cases. For example, doing a particular action periodically with a statement like this:

  if (gametime%triggerperiod == 0) { do_something; }

no longer works, as the float version of '%' will be used! This can be remedied in a quick and dirty way like this:

  if ((int)gametime % triggerperiod == 0) { do_something; }

But if you want this code to work properly for different game speeds, however, use StdGame.checkTime, which uses the correct logic for this:

  if (checkTime(triggerperiod)) { do_something; }

3.1 -> 3.2

JGObject's finalize() has been renamed to destroy() to prevent name clash problems.

Game generator

JGame now comes with a (prototype) game generator (Gamegen). This is a tool for generating a prototype game without any programming. Basically you fill in a set of parameters, which together determine the dynamics of the game. It is based on the JGame basic concepts, such as tiles and object types, which means you may need to read the docs to understand precisely what every parameter does. Gamegen is meant for web-based deployment. There is PHP code for filling in the parameters in a neat form, but it is also possible (but not as easy) to use it without PHP or a web server. This tool is still in development stages, as it isn't very robust or polished, and should in the future generate neat Java code, which can be used to generate quick templates to jump start game development. It is available online on the JGame website; check out the website if you want to take a look at this tool. If you want to use it in any other way, see the gamegen/README file. A generalised non-PHP version is work in progress.

Java 1.2

JGame should work perfectly well with Jdk 1.2, as it is periodically tested on a Java 1.2 system. However, the Java 1.4 install that I have is not capable of producing Java 1.2 classes, as the "-source 1.2" and "-target 1.2" compiler options do not work as they should. Sun refuses to look at the bugs, as Java 1.2 is considered "retired" (btw, 1.3 still isn't). So, if you really want to run it on Java 1.2 because you can't upgrade for some reason, you have to recompile the classes and regenerate the Jar. If there is a problem with your 1.2 install, please contact me.