May 2, 1997
Molybdenum is a Java applet that implements the rudiments of a strategy game. It is unique because it has a 3D playing arena. The player can move around Known Space in 3D using keystrokes, and can get information about bases and move ships using the mouse. Each of the sections below describes one of the areas where Molybdenum improved upon our last assignment - walking through a maze with texture-mapped walls.
Molybdenum was conceived as a game for one or more players, with the possibility of computer players. The game space is populated by "bases," which can be planets or asteroids or space stations - they are a spot in space that supports people and builds ships. "Ships" are the other type of object in game space. Ships orbit bases, and are built by bases; they cannot float in free space. At the end of a turn, ships may move to a new base, if the player directed them to. If more than one ship arrives at a base, the ships fight, and the winner ends up circling the base when the new turn begins.
Players can get information about a base by clicking on it. Its highlight color shows which player owns it, and its population is reported in the status area. Players can move a ship by dragging it to a new base - highlights and a drag line help the player see what the result of a drag will be.
When the user clicks on the screen, I need to figure out what that pixel position corresponds to in the world coordinates of game space. I know where the eye is, and what the direction of the view and up vectors are in world coordinates. I use this knowledge along with the width and position of the screen relative to the DOV to calculate the world coordinates of the user's click. Then I form a vector from the eye point to that click point. Finally, for each object in game space, I inverse transform the vector into object coordinates, and use a bounding box intersection routine (supplied by Kenny Hoff) to find out if the vector intersects the object's bounding box. This routine also parameterizes the vector and finds the parameter value of the intersection with the bounding box, so if the vector hits more than one bounding box, I can choose the one with the closest intersection point.
When I discover that an object has been hit, I draw its bounding box using the XOR paint mode provided by Java. This avoids having to re-draw the whole screen, and I can just draw the box again to erase it. When the user drags a ship to a new base, I use the XOR mode again each time the mouse is moved to erase the old line and draw the new line. It is harder than I expected to get this right, especially starting and terminating the drag so that no leftover lines are visible.
I use a new file format to read the objects in my world.
This file format reflects the way the program operates internally as well. Objects in the world are kept in a display list, and whenever I need to redraw the world, I perform the transformations and scan-conversion for each object in that list. When a ship is destroyed, I remove it from the display list, and when a ship is built, I add it to the display list.
There are two types of objects displayed in game space, "Kbase" and "Kship." These both overload the "Gobject" class, which is the general class for drawing a group of triangles. Kbase and Kship add information for game mechanics, like strength and population. Bases track whether there is a ship circling, and resolve battles between incoming ships. Ships keep track of which base they are circling, and can "spawn" a copy of themselves, in case the player splits up a fleet. When the turn ends, I step through the display list to determine actions that need to be taken, and although the display list stores Gobjects, I can tell whether an object is a Kship or Kbase using Java's instanceof operator, and take appropriate actions. End of turn actions require three iterations through the display list; this was also considerably more complicated than I expected.
I also made many other changes. The space where the 3D game space is drawn is now a Canvas, rather than being drawn directly into the Applet window, so I can put other AWT components around it. My modularization is somewhat questionable, but it developed in the direction that was useful at the time. My quest for a faster way to get an array of colors in memory onto the screen has been in vain so far - but the quest continues.
The project took at least 40 hours of work, which brings the total Java programming time for the semester to 100-120 hours.
Last modified May 1, 1997