Once you have learned how to program games in Java, you will want to be able to deploy them on different types of deployment frameworks. This article will cover browser applets, executable JARs, and Java Web Start. It is excerpted from the book Advanced Java Game Programming written by David Wallace Croft (Apress, 2004; ISBN 1590591232).
Deployment Frameworks - Reading from a JAR File (Page 2 of 9 )
A Java archive ( JAR) file is simply a compressed zip file containing all the code and multimedia files that you need for your game. It greatly reduces the amount of time that is required to launch your applet because players can download the game in a single HTTP request.
Before JAR files, one of the techniques developers used to reduce applet download times was to copy all the images to a single file. As shown in Figure 2-1, the individual smaller images would be located at different positions in the larger combined image in the form of a grid or a strip. Coordinate data and custom code was then used to cut out rectangles of image data from the different positions within the combined image once downloaded. Fortunately with JAR files today, such additional code is no longer necessary. You can access the individual images simply by opening them by their unique file names and directory paths relative to the archive root. If you have a sprite set that comes to you as a single image, you probably want to crop it into smaller images using an image editor before deployment. If for some reason you do need to crop smaller images from a larger image during run time, you can use the static method crop() in class ImageLib of package com.croftsoft.core.awt.image for that purpose.
Figure 2-1.Ari Feldman's "1945" Sprite set. Artwork copyright 2002, 2003 by Ari Feldman.
Another pre-JAR complication Java applet developers used to have to deal with was writing code to delay using an image until it was completely downloaded. In the early days of the Web, Internet connections were so slow that browsers would display incomplete image data as it was downloading so users could get a sense of what was coming and decide whether it was worth the wait. Applet developers that did not want to use an image until it was entirely loaded used the class java.awt.MediaTracker to track the progress of the download. This was especially important as HTTP requests were less reliable back then and sometimes requests to download images would fail completely. If game programmers did not track this, game players would occasionally be frustrated by playing shoot-em-up against enemy sprites that had the unfair advantage of invisibility due to a bad Internet connection.
Fortunately the necessity to program all that tracking, stalling, and download request reattempt logic goes away when you simply include your multimedia files in the same JAR file as your code. When you take this approach, you know your game code is guaranteed to load your images reliably and quickly without needing to resort to special precautions. If by chance your images do fail to download successfully, you cannot do much about it, as your code probably did not download either because it was in the same package.
One of the catches to placing all your image and other resource files within a JAR file is that you need to access these files using the java.lang.ClassLoader getResource() method. The ClassLoader reference that you use for this purpose must come from a class that is in the same JAR file as the resource file you are trying to access. This is because classes loaded from different JAR files are assigned their own ClassLoaders. The path and file name argument to the getResource() method is then relative to the root of the JAR file that is associated with that instance of the ClassLoader.
Another trick to this is that your path and file name argument to the getResource() method, although relative to the root of the JAR archive, must not be preceded by a leading forward slash (/) to indicate the root directory. For example, media/dodger/bang.wav would work but /media/dodger/bang.wav would not. This is different from using the getResource() method to pull files from the hard drive outside of the JAR file.
Upgrading Clients with the Plug-In
One of the main problems with applets embedded in browser clients is that many of them only support older versions of Java such as 1.1. I have always held the position that it is better to upgrade the client rather than downgrade the code and the skills of the developer. Upgrading the client is not as easy as asking your users to upgrade to the latest version of their favorite browser, however, as the latest version might still contain old versions of Java. For example, at the time of this writing, Internet Explorer ships with Java 1.1 and Netscape with Java 1.3. Because this book promotes code based upon Java 1.4, this can be a problem.
To the rescue is the Java Plug-in, formerly known as the Activator. It upgrades the version of Java embedded in your browser when your favorite browser vendor will not. It does this by adding special tags to the HTML web page that contain instructions to treat the applet like a browser plug-in. When the browser determines it does not have the required version of the plug-in, it prompts the user to download the latest version.
Except for a few liberties that I have taken to wrap long lines to fit the page, the preceding code is what the page looks like after conversion by the Java Plug-in.
The Java Plug-in tool that performs the conversion is called, appropriately enough, HtmlConverter. It resides in the bin subdirectory of your Java SDK installation. It has both a command-line and a graphical user interface (GUI).
C:\jdk\bin\HtmlConverter.exe -backup original -latest index.html
The preceding code is the command that I used to convert the page. The name of the file to be converted is index.html. Because HtmlConverter replaces the original file, I had it save a backup copy to a subdirectory called original. I also told it to allow the use of any version of Java on the client machine that is the same as or later than the latest version of Java. If I did not include the -latest option, the code would require the user to download a specific version of Java, even when a later version might already be installed.
The Java Plug-in has many more features beyond what I have mentioned here. The 150+ page online book Java Plug-in 1.4.2 Developer Guide describes these features in detail.2
Knowing Your Limitations
Browser applets run within a security sandbox on the client where they can play without being able to cause harm. This means that there are restrictions on what an applet can do. Much to the relief of users surfing the Web, downloaded applets do not, for example, have read and write access to their hard drives. To prevent applets from using the client machine as a platform to stage an attack on other machines on the Internet, applets can only create network connections back to the server from which they were downloaded. Keep in mind that the server contacted must be the same one from which the applet was down-loaded—the codebase—which is not always the same as the server for the HTML web page that contains the embedded applet—the document base.
There are other additional restraints but these are the two that might be the most onerous to the game developer. The inability to access the hard drive makes it impossible to save the high scores or the preference settings for a player. The inability to contact machines other than the applet server means that game applets cannot contact other peer machines directly for multi-user game play.
The way to get around both these limitations is to perform these functions through the applet codebase server. After prompting the player for a user name and password, the applet can make a network connection back to the applet server to load user data. Later the applet can make another network connection to save the game state on the server when the player chooses to do so, or automatically at periodic intervals during play. In the case of multi-user play, all messages between players are routed to each other indirectly through the central server. For example, when the sprite of one player moves in a virtual space, the applet views of the other players are updated by a message passed first from the acting applet to the applet server and then from there to the receiving applets.
Applet networking, including applet-servlet messaging with firewall tunneling capability, is covered in detail in the last three chapters of this book.
This article is excerpted from Advanced Java Game Programming by David Wallace Croft (Apress, 2004; ISBN 1590591232). Check it out at your favorite bookstore today. Buy this book now.