P.T.Cruiser

  by Ben Reichardt and Alex Pekker

You are in the middle of the Pacific Ocean. You need to pick up all the golden stars before the enemy boats close in and kill you. Don't be afraid to blow them to smithereens first!

  Email: breic@stanford.edu, apekker@stanford.edu

Controls

The movement controls are

            w
     a              s
            z
To shoot, press 'q'.

Features   Required functionality

Advanced features Of all these features, the most difficult to implement were the level of detail control for the water (clean meshing between areas of different detail levels is complicated) and the texture-mapped wake behind the player (difficult to derive an appropriate wave motion physics function, to tweak all the parameters to get reasonable output, and finally, to place the texture on top of the surface texture in the right position).

Implementation notes Everything was programmed in C, on and for MacOS X. The exact same code compiles and runs for Linux. More information can be found in the source code. While we were unable to fully comment all the source code, we have tried to at the very least put comments in the header files to explain what the various packages do.

To compile PTCruiser on UNIX platforms, type "make -f Makefile.platform", where platform is either sun4 or linux. An executable "game.platform" will be created, which can then be run.

Texture and model sources The water texture used to be a standard MacOS desktop background pattern. The horizon texture is just a random image of the sky, which I modified in order to have it loop 360 degrees. I also drew the radar background texture. The numbers are taken from Quake3Arena, as are the rocket textures and the rocket model. The boat model is taken from poserworld.com/models2.htm. We used 3D Exploration (www.xdsoft.com/explorer) as a free tool for exporting .obj files as OpenGL code. We used (custom modified) texture-loading code from David Blythe's SIGGRAPH '96 Advanced OpenGL course notes.

Sources of inspiration John F. Kennedy, and his experience on PT Boats during World War II. Patrick O'Brian, for his seafaring tales. The Macintosh game Spectre for the basic gameplay (get all the goals while avoiding obstacles and killing enemies).

The score is on the left, the radar on the right. Note that the sinking enemy ship's engine has turned off. Pretty water, no? (The visual artifacts in the upper left are due to the screen grab program.)

Notice the turbulent wake behind the player's boat. These screen shots don't really do justice to the motion of the water and the textures, and the dynamic generation of the textures. These rockets are taken from Quake3Arena.

Another nice screen shot. We worked hard to eliminate visual artifacts with as little work as possible. For example, we do not use the depth buffer when we draw the water because it is always drawn from back to front. These screen shots haven't shown it, but we also sort the semi-transparent flames so they are drawn from back to front (the depth buffer can't be used then).


Note on the time-dependent filter kernel for simulating wave motion: The filter function in ripples.c is, in pseudocode, approximately   "dest(x, y) = (source(x - 1, y) + source(x + 1, y) + source(x, y - 1) + source(x, y + 1)) / 4 - dest(x, y)"  . (The actual kernel is slightly more complicated.) Here, dest is the height array we are copying into (the next frame, which initially contains the data from the previous frame), and source is is height array for the current frame. The neutral height is at 0. Thus, the next height is the average of currently neighboring heights, minus the offset of the previous height. A heuristic argument for this function is: we average because waves should smoothly interpolate values; we subtract the previous height because its offset from zero indicates the amount that the height field should be relaxed (that is, the velocity in the vertical direction). Since there is a time delay, we get wave motion, rather than just smooth averaging.