3D Game Programming All in One (Course Technology PTR Game Development Series)
Torque uses the concept of datablocks and profiles to help define and organize resources for use in the game. We encountered this concept when building our Emaga sample games in earlier chapters.
There are essentially two ways to make sounds occur in a Torque game. We can directly activate a sound (or music, for that matter) with program code, or we can attach sounds to in-game objects and let the Torque Engine activate and control the sounds indirectly on our behalf.
Most of the time we will use the latter—indirect—approach because once the relationship of sound-effects file to object has been defined in the right place, we don't need to worry about it anymore.
However, the first approach—direct activation—is more flexible. We'll look at both approaches in the remainder of this chapter.
Audio Descriptions
Audio datablocks are used no matter whether we directly or indirectly activate sounds. Audio datablocks are defined using the keyword AudioDescription when they are defined. Here is an example of an audio datablock:
new AudioDescription(AudioTest) { volume = 1.0; isLooping= false; is3D = false; type = 0; };
In this example, AudioTest is the handle to this description.
The volume property indicates the default volume for this channel. This property is itself not changeable, but when the audio channel is used, the volume can be changed via script statements.
The property isLooping indicates whether to repeat the sound after it has finished playing.
The is3D property is used to tell Torque whether this channel needs to be processed to produce positional information.
The type property is essentially the channel for this sound. All sounds on a given channel can be controlled via script statements that are channel specific.
With this datablock we have defined the nature of the AudioTest sound, so to speak—its characteristics. However, there's obviously not enough here to actually produce any sound. We need at least a sound file with a sample waveform in it, and then we need to associate that file with the appropriate AudioDescription. This is how we do it programmatically:
$Test = alxCreateSource("AudioTest",expandFilename("~/data/sound/test.wav"));
This statement creates an audio object. The first parameter is the datablock we saw earlier. The second parameter first invokes a call to the expandFilename function, which knows how to make sure it finds the correct full path of the file. The return value is a handle to the actual audio object created by Torque.
Now to activate the sound, we simply call the following:
alxPlay ($Test);
As you see, we just needed to tell alxPlay the name of the object, and away it goes.
We can adjust the volume for this playback, but we need to do it before we play the sound. We do that this way:
alxListenerf(AL_GAIN_LINEAR, %volume); $Test = alxCreateSource("AudioTest",expandFilename("~/data/sound/test.wav")); alxPlay ($Test);
The alxListenerf function sets the volume for the listener (the player) and does it using a linear (versus logarithmic) gain (amplification) adjustment. With a linear gain, a volume of 0.5 is half as loud as a volume of 1.0. With the nonlinear (logarithmic) gain, a volume of 0.5 is about two-thirds as loud as a volume of 1.0.
Note that this volume adjustment is performed on the value of the volume in the data-block, where the volume was set to 1.0.
So if we call alxListenerf with a volume of 0.75, then the actual volume would be 0.75 multiplied by 1.0, or 0.75—and all loudness calculations would follow from that. If we call alxListenerf with a volume of 0.75, and if the datablock's volume had been set to 0.5, then the actual volume would be 0.75 multiplied by 0.5, or 0.375.
Now using alxPlay this way is useful for sounds that have no positional information requirements, like GUI button beeps or the sound of a player's throbbing headache. But what if we want to place the sound in the game world?
In this case, we need to first create a profile:
new AudioProfile(AudioTestProfile) { filename = "~/data/sound/test.wav"; description = "AudioTest"; };
Notice that now the file name is contained in the profile. The second property, description, points to the datablock we defined earlier. We then activate the sound as follows:
alxPlay(AudioTestProfile, 100, 100, 100);
Notice now that the function call refers to the profile, not the description datablock. The three parameters that follow define a location in 3D coordinates in the game world. The sound, when played, will seem to come from that location. It's important to understand that when activating sounds in this manner, you must ensure that the sound file contains a monophonic sound, and not stereo. Also, the is3D property in the datablock must be set to false.
Tip | Take note of whether you are creating the AudioDescription or AudioProfile on the client or the server. On the client, you define it this way: new AudioDescription(AudioTest) { }; and new AudioProfile(AudioTestProfile) { } If the code resides on the server, do it this way: datablock AudioDescription(AudioTest) { }; and datablock AudioProfile(AudioTestProfile) { } In point of fact, this rule applies for all datablock types, because the server can only define true datablocks. |
Trying It Out
Let's try it out, using your Emaga6 sample game. Open up your root main file (main.cs) and add the following lines to the very top:
new AudioDescription(AudioTest) { volume = 1.0; isLooping= false; is3D = false; type = 0; }; new AudioProfile(AudioTestProfile) { filename = "~/data/sound/test.wav"; description = "AudioTest"; preload = true; }; function AudioTestA(%volume) { echo("AudioTest volume="@%volume); alxListenerf(AL_GAIN_LINEAR, %volume); $pref::Audio::masterVolume = %volume; $AudioTestHandleA = alxCreateSource("AudioTest", expandFilename("~/data/sound/test.wav")); echo("AudioTest object="@$AudioTestHandleA); alxPlay($AudioTestHandleA); } function AudioTestB(%volume) { echo("AudioTest volume="@%volume); alxListenerf(AL_GAIN_LINEAR, %volume); $pref::Audio::masterVolume = %volume; alxPlay(AudioTestProfile, 100, 100, 100); }
Now launch your game. After you've spawned in, open the console window (using the Tilde key) and type in the following:
AudioTestA(1.0);
You should hear the "electronic drip" test sound. Play with the volume setting, trying different values less than 1.0.
Next type this into the console window:
AudioTestB(1.0);
You should hear the electronic drip test sound again, but this time seeming to come from a specific direction.
Again, play with the volume setting, trying different values less than 1.0. You can also play with the 3D coordinate values in the call to alxPlay() in the AudioTestB() function.
Категории