Controlling the Gun


The Sound of Shooting

Java 3D has three kinds of sound node classes. All three are subclasses of the Sound class.


BackgroundSound

A BackgroundSound node allows a sound to permeate the entire scene, located at no particular place.


PointSound

A PointSound node has a location, so its volume varies as the user moves (or as the sound node moves). I use PointSound nodes for the laser-beam and explosion sounds in Shooter3D.


ConeSound

A ConeSound node is a PointSound that can be aimed in a particular direction.

Before sound nodes can be added to a scene, an audio device must be created and linked to the Viewer object. This is simple if the SimpleUniverse utility class is being used (as in this example):

     AudioDevice audioDev = su.getViewer(  ).createAudioDevice(  ); 

This line of code appears in the WrapShooter3D constructor.


SimpleUniverse was introduced in Chapter 14; it builds the view branch part of the scene graph, which specifies how the user's viewpoint is positioned in the world and includes the Viewer object.

WrapShooter3D uses initSound( ) to load a WAV sound file and create a PointSound object:

     private PointSound initSound(String filename)     { MediaContainer soundMC = null;       try {         soundMC = new MediaContainer("file:sounds/" + filename);         soundMC.setCacheEnable(true);   // load sound into container       }       catch (Exception ex)       {  System.out.println(ex); }           // create a point sound       PointSound ps = new PointSound(  );       ps.setSchedulingBounds( bounds );       ps.setSoundData( soundMC );           ps.setInitialGain(1.0f);  // full on sound from the start           // allow sound to be switched on/off & its position to be moved       ps.setCapability(PointSound.ALLOW_ENABLE_WRITE);       ps.setCapability(PointSound.ALLOW_POSITION_WRITE);           System.out.println("PointSound created from sounds/" + filename);       return ps;     } // end of initSound(  ) 

A Sound node needs a sound source, which is loaded with a MediaContainer object. Loading can be done from a URL, local file, or input stream; the try/catch block handles invalid filenames, as well as problems with opening files. initSound( ) loads its sound from a local file in the subdirectory sounds/.

All Sound nodes must be given a bounding region and assigned a sound source:

     PointSound ps = new PointSound(  );     ps.setSchedulingBounds( bounds );     ps.setSoundData( soundMC ); 

To play, the sound node must be enabled with setEnable( ). initSound( ) doesn't call setEnable( ) since the sound isn't played when first loaded. Instead, the node's capability bits are set to allow it to be enabled and disabled during execution:

     ps.setCapability(PointSound.ALLOW_ENABLE_WRITE); 

The explosion sound will be positioned at runtime, requiring another capability bit:

     ps.setCapability(PointSound.ALLOW_POSITION_WRITE); 

Other sound elements include setting the volume and saying whether the sound should loop (and if so, then how many times). The relevant methods are:

     void setInitialGain(float volume);     void setLoop(int loopTimes); 

initSound( ) sets the volume to 1.0f (full-on) and uses the default looping behavior (play once, finish). PointSound nodes have a location in space, given by setPosition( ). They emit sound in all directions, so attenuation factors can be specified in a similar way to Java 3D PointLight nodes.

Problems with Sound

The Sound classes in the current version of Java 3D (v.1.3.1) contain some severe bugs, including poor volume adjustment when the user moves away from a Java 3D PointSound or ConeSound node, strange interactions between multiple sounds at different locations, and anomalies between left and right ear sounds. There are plans to fix these bugs in the next major Java 3D version, 1.4.




Killer Game Programming in Java
Killer Game Programming in Java
ISBN: 0596007302
EAN: 2147483647
Year: 2006
Pages: 340

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net