Skip to main content

Building a Java applet-based game -- why don't we see more of them?

Posted by jfalkner on November 1, 2007 at 6:35 PM PDT

My brother and I decided to try and make a viral video game. The sort of game that can suck hours away from your life. The type of game that passes the boring times at work. The type of game that normally seems to be coded in Flash/ActionScript....

The only problem is that neither of us knows how to code Flash/ActionScript. After some thought, we wondered if this was actually a problem. We do know how to code in Java, and Java does have applets. This page is to document our efforts and hopefully provide some information for other Java game programmers that want to use applets. What this blog won't provide is any information about how to make a fun game -- we're not even sure if we've done that ourselves.

Please do post any questions or comments that you think would be helpful. If you know something we've missed, I'll gladly add it to this page.

Lessons Learned From Coding a Java Applet-based Game

  1. About the game
  2. Applets are easy to code, but Swing wasn't terribly helpful
  3. The tag only sort of works
  4. Profiling your game can really speed things up
  5. The game seems to work...feedback will be posted
  6. About the game

    This is the only place that you'll find information about the game. It is nice that we'll get a link to it, but this entry is intended to convey what we've learned about using Java to make a simple game.

    Link to Game: Rise of the Robots (RotR)

    Please don't post non-Java related comments about this game in this blog's discussion section.

    Applets are easy to code, but Swing wasn't terribly helpful

    Something I like about Java is that tools like Netbeans and Eclipse make coding relatively easy. They are free to download and use. The IDEs also making coding, compiling, and deploying a JAR a breeze. The rate limiting step seems to be figuring out how to actually code what you want to code.

    We knew a good deal about Swing before starting to code this project. This resulted in the initial program only took a weekend worth of work. All of the graphics are 2D and are drawn essentially in one massive override of the paintComponent() method. Initially, we tried to be clever with JButton, JLabel, JPanel, and such; however, it quickly became clear that it was far easier to make most every bit of text a PNG graphic. The result looked much better, and it only took a few minutes to whip up some graphics via Inkscape and GIMP.

    After adding in a few graphics we did realize that the size of the final JAR was starting to grow. In the end we ended up with a JAR that was about 200 KB in size. Not bad at all in my opinion, and well worth the time saved on messing around with Java fonts and cleverly positioned JButtons.

    Anti-alias text or it'll look bad

    In the end, we did use standard Java fonts to draw some text in the game. In every case it was clear that anti-aliasing is a must. Otherwise the text looks awful. You can easily do this by adding the following to your code in the paint() or paintComponent() method.

    // conver to graphics 2D for anti-alias
    Graphics2D g = (Graphics2D)frame.getGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

    The applet tag only sort of works

    It turns out that the intuitively named HTML tag doesn't do what you think. It used to, but these days you are expected to use a more generic tag for embedding content in to a HTML page. Sun's JDK documentation explains it pretty well. Here is the page of interest.

    Prompting to install required Java version

    If you do not include information regarding the required Java install, your game might not work. We discovered this after compiling our code with Java 1.5. Most users could play the game perfectly fine; however, several users reported that the applet simply didn't work. Java 1.5 bytecode isn't compatible with earlier Java releases, and the applet's classloader was throwing an incompatible version error.

    The solution was relatively easy. Set the type parameter to be "application/x-java-applet;version=1.5" and replace the 1.5 with whatever is the appropriate version. Here are two examples. One with the tag (Firefox/Netscape) and one for the tag (MSIE).

      <embed code="feu.td.Game.class" 
             archive="./Game.jar"
             width="500"
             height="490"
             type="application/x-java-applet;version=1.5"></embed>

    Above is the tag example. Below is the tag example.

    <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
            width="500"
            height="490">
            <PARAM name="archive" value="./Game.jar">
            <PARAM name="code" value="feu.td.Game.class">
            <PARAM NAME="type" VALUE="application/x-java-applet;version=1.5">
    </OBJECT>

    Profiling the game can really speed things up

    Profiling is an important part of any Java project. It will tell you how much time each portion of your code is taking. Thus, if your code is slow or maxing out the processor, you can profile to try and discover where optimizations are required in the source-code. The Netbeans profiler is awesome. It is free and easily installs. After you install it you can simply right-click on your code and "Profile".

    I strongly suggest trying it out. The initial version of my game would take up to 50% of the processor on my 2.0Ghz machine when about two dozen sprites were walking on the screen. After a few hundred sprites, the game would be noticeably jumpy and not much fun to play. A few rounds with the profiler and it was clear where I unnecessarily wasted processor cycles. Post profiling the game now takes less than 10% of my CPU, even when the screen is full of sprites.

    Recycle a BufferedImage object all the time. Always double buffer!

    It is very expensive to constantly use the Graphics object to draw on the screen. Never do this. Instead draw absolutely everything to a in-memory BufferedImage object. Also, only make one object and recycle it every time you need to draw a frame of the game.

    Here is how you can make a BufferedImage object. Be sure to make it the same size as the game's display.

    // make and buffer the map background
    BufferedImage bufferedBackground = new BufferedImage(Game.BOARD_WIDTH, Game.BOARD_HEIGHT, BufferedImage.TYPE_INT_RGB);

    // in the paintComponent() method use the buffered graphics
    public void paintComponent(Graphics graphics) {
    // draw on the bufferedBackground ...
    Graphics2D g = (Graphics2D)bufferedBackground.getGraphics();

    // use g instead of graphics...
    }

    After an entire frame of the game is drawn in-memory. Draw once to the actual screen of the game. Here is a code snippet showing how this is done with the Graphics object.

    public void paintComponent(Graphics graphics) {
    // draw on the bufferedBackground ...

    // draw the final image
    graphics.drawImage(bufferedBackground, 0, 0, null);

    ...
    }

    The game seems to work...feedback will be posted

    It seems that the first version of the game looks fine. For two Java coders that are moderately artistic, we made the game not look like garbage. Plus it seems to play fine.

    It'll be interesting to see if this followup section ends up being boring. In the least, I'll follow up with a comment saying that the game seems to be fine. There is no great reason that a Java-based viral video game can't work.

    Related Topics >>