Adding Sound Effects to Your Game

Boom! Smack! Whack! What do these three words have in common? They all describe sounds. Sounds surround you every day, and are transmitted through the air, through water, through solid objects, and as vibrations. Listening to anything from the dishwasher to a lawnmower, sounds tell you what is going on in the world around you. Hearing is the second most important sense (after sight). Many years ago, before the invention of the television, sound played an important role by entertaining many through radio. Radio, known as the theater of the imagination, highlighted many family evenings. This theater didn't have spectacular visual effects, so it relied on something else—sound effects. The creaking door in "The Shadow" let you know that the house was haunted.

This chapter will introduce you to the commands built into DarkBASIC so you can create ear-popping sound effects. It will give you a tour of loading, playing, and positioning sound effects. You will learn all about 3D positional sound effects. In the end, you will create a game based almost completely on sound. This chapter will literally surround you with sound effects.

Introduction to Sound

Picture a world without sound. It's not hard to do. Just watch TV sometime and hit the mute button. What a difference! Imagine watching the big screen without the thunderous speaker systems in a theater. The show might be watchable, but the whole experience is changed without audio. The ear is a marvelous part of the body. It can pick up a wide range of sounds and then translate sound waves into signals that the brain can understand. From a bass violin in an orchestra to a hot rod squealing its tires, there is a huge range of possible sounds, and the human ear can hear a wide range of those audio frequencies. Surprisingly, that is also how computers read sound. Audio is stored in a file as a digital recording of an analog sound signal, recorded with a simple microphone or by other means.

What Does a Sound Look Like?

Can you see a sound? Of course not! You can't see sound any more than you can see the wind. However, you can see the effect of wind. By the same token, you can see what a sound looks like by observing its effects. Every sound affects your eardrum by vibrating the particles in the air. These particles are vibrated in a pattern, so observing this pattern allows you to see the sound.

The patterns generated by sounds can be represented by sine waves. No matter how simple or how complex the sound, it can always be described as a series of sine waves of varying amplitudes and frequencies. Figure 13.1 shows a sample sine wave.

click to expand
Figure 13.1: A typical sound wave

The frequency is the number of times that a sound wave rises and falls over a period of time, usually measured in hertz (hz). The amplitude is the height and depth of a single sound wave.

Sampling the Sound

Sound in the analog wave format presents a problem for the computer, which only knows how to represent data in terms of 1s and 0s. A sound wave has more than two states attached to it, so the sound wave must be digitized.

Your sound card handles the mechanics of digitizing the sound waves. The sound card takes "snapshots" of the sound wave at different intervals in a process called sampling. Unlike a video camera, which takes between 24 and 30 pictures per second, the sound card samples a sound many thousand times per second.

The sound wave's frequency is the number of times it rises and falls over a period of time. A sound wave's sampling rate is also called the frequency because it samples the sound at a specific number of times per second. A CD-quality sound is sampled at 44 hz (samples per second).

Bit Rate

When you sample a sound, a bit rate is established. This represents the amount of bits used to describe a single sample of sound. Because every sound varies in amplitude, a bit rate needs to be established to represent the height (or depth) of the amplitude. Bit rates are generally referred to by the number of bits each sample contains. A CD-quality sound has a bit rate of 16 bits, which means that every sample in the sound has a total of 16 bits of data to it.

The Wave Sound Format

A wave file (usually with an extension of .WAV) is one file type that contains a digital representation of a sound wave. It contains all the samplings of an analog sound file. There are many similar file formats, but .WAV is the sound format used most for sound effects. Other sound formats include Mpeg Layer 3 (.MP3), Audio format (.AU), and Real Audio (.RA).

Creating Wave Files

There are many different ways you can create a wave file. Windows comes with a program called Sound Recorder that uses a microphone to create waves. A more professional approach would be to use Cool Edit 2000 or some other wave editing software. You can also download pre-recorded sound effect wave files from many different Web sites.

Some of the easiest sound effects are those you can create with your mouth. Using a microphone and your imagination, you can make cows moo and dogs bark. If you're even more creative, you can make dogs moo and cows bark. Your imagination is the limit.


Creating and Loading Sounds

Loading sounds in DarkBASIC is very simple. There is no need to create a sound device, set the parameters, set up buffers, and cross your fingers. It takes one command to load a sound; DarkBASIC does all the hard work for you.

Using the Sound Loading Commands

DarkBASIC stores all sound effects in buffers, which are addressed by an integer number. It is a good idea to keep track of what buffer goes with what sound effect at the top of your file or on a separate notepad. You do not want to play the "game won" sound effect when the player just lost all their points.

The LOAD SOUND Command

The LOAD SOUND command is the most basic sound-loading command. The syntax for this command is

LOAD SOUND "File Name", Sound Number

Here are some examples of using the LOAD SOUND command:

LOAD SOUND "yeah.wav", 13
LOAD SOUND "bummer.wav", 14

The LOAD 3DSOUND Command

The LOAD 3DSOUND command is the same as the LOAD SOUND command, but with a twist. This command marks the buffer sound number into which it is loaded with a special flag that denotes it as a 3D sound. The syntax for this command is

LOAD 3DSOUND "File Name, Sound Number"

Here are some examples of using the LOAD 3DSOUND command:

LOAD 3DSOUND "meow.wav", 1
LOAD 3DSOUND "bark.wav", 1

The CLONE SOUND Command

The CLONE SOUND command clones a sound into a specified sound buffer. The advantage to using a cloned sound is that you can play more than one copy of a sound with one set of sound data, saving valuable memory for other things. The syntax for this command is

CLONE SOUND Destination Sound Number, Source Sound Number

Here is an example of the CLONE SOUND command:

CLONE SOUND 4,114

The DELETE SOUND command

Another memory-saving technique is to use the DELETE SOUND command when you no longer need a sound. This also allows you to re-use a sound buffer for another sound effect. Just like a bitmap, you can load a sound over another sound, but it's always wise to delete a sound buffer before re-using it. The syntax for the DELETE SOUND command is

DELETE SOUND Sound Number

Here are some examples of the DELETE SOUND command:

DELETE SOUND 13
DELETE SOUND 14

The SOUND EXIST Command

How do you know whether a sound has been loaded? By using the SOUND EXIST command. This command returns a 0 if the sound does not exist and a 1 if it does. The syntax for this command is

SOUND EXIST (Sound Number)

Notice that the sound number is surrounded by parentheses.

The Sound Sample program uses all the commands you have learned up to this point. Figure 13.2 shows the output of the program. You will find this program (and all the other programs in this chapter) in the SourcesChapter14 subfolder on the CD.

click to expand
Figure 13.2: The Sound Sample program demonstrates the use of some basic sound commands.


REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Sound Sample program
---------------------------------
REMEND
DIM answer$(2)
answer$(0) = "not exist!"
answer$(1) = "exist!"
LOAD SOUND "yeah.wav", 1
LOAD SOUND "bummer.wav", 2
LOAD 3DSOUND "yeah.wav", 3

CLONE SOUND 4,2
DoorOpenLoaded = SOUND EXIST(1)

FOR x = 1 TO 6
 SoundIsThere = SOUND EXIST(x)
 tempstring$ = "Sound #"+STR$(x)+" does "+answer$(SoundIsThere)
 PRINT tempstring$
NEXT x
DELETE SOUND 1
DELETE SOUND 2
DELETE SOUND 3
DELETE SOUND 4
WAIT KEY


Playing Sounds

Boom! The enemy ship just exploded and you can hear it. Now you get to program the playing of the sounds. After the sounds are loaded, you can use them in the game. Playing back sounds is just as easy as loading them. You don't need to know the frequency of the sound or the timing of the sound card; just a simple command and presto, you hear the firepower of your awesome ship blasting away another alien scumbag.

Using the Sound Playback Commands

The sound playback commands use the same integer buffers as the load commands. They also give you a few more options for playback control. It only takes one command to play back a sound.

The PLAY SOUND Command

The PLAY SOUND command is the most basic sound-playback command. You can specify an optional start position in bytes that tells DarkBASIC to start the sample at that position. The syntax for this command is

PLAY SOUND Sound Number, Start Position

Here are some examples of the PLAY SOUND command:

PLAY SOUND 5
PLAY SOUND 5, 30000

The LOOP SOUND Command

The LOOP SOUND command allows you to repeat a sound. It is handy so you don't have to keep using the PLAY SOUND command. This command allows you to specify a starting position in bytes, as well as an ending position and an initial position. The ending position is where the sound will stop and then start over at the starting position. The initial position is where you want the first loop to start. The syntax for this command is

LOOP SOUND Sound Number, Start Position, End Position, Initial Position

Here are some examples of the LOOP SOUND command:

LOOP SOUND 5
LOOP SOUND 5,3000
LOOP SOUND 5,3000,5000
LOOP SOUND 5,3000,5000,2500

The STOP SOUND Command

The STOP SOUND command does just that—stops a sound. You can use this feature on looping or non-looping sounds. The syntax for this command is

STOP SOUND Sound Number

Here are a few examples of the STOP SOUND command:

STOP SOUND 5
STOP SOUND 1

The PAUSE SOUND Command

The PAUSE SOUND command pauses a sound while it is playing or looping. It is used in conjunction with the RESUME SOUND command. This syntax for this command is

PAUSE SOUND Sound Number

Here are a few examples of the PAUSE SOUND command:

PAUSE SOUND 1
PAUSE SOUND 5

The RESUME SOUND Command

The RESUME SOUND command starts playing a sound at the point where it was last paused. This command must be used in conjunction with the PAUSE command, and it can provide some interesting effects. The syntax for this command is

RESUME SOUND Sound Number

The Resume Sound program uses the commands you have learned up to this point. It pauses and resumes a sound during playback. Figure 13.3 displays the output of this program.

click to expand
Figure 13.3: The Resume Sound program demonstrates the use of the PAUSE SOUND and RESUME SOUND commands.


'---------------------------------
'Beginner's Guide To Game Programming With DarkBASIC
'Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
'Chapter 13 - Resume Sound program
'---------------------------------

' Loads the sound
LOAD SOUND "talking.wav", 5

' Start looping the talking wave
PRINT "Hal"
PLAY SOUND 5
' wait for 1 second
SLEEP 500
' pause the wave
PAUSE SOUND 5
' wait for 1 second
SLEEP 500

' Resume the sound
PRINT "lei"
RESUME SOUND 5
' wait for 1 second
SLEEP 500
' pause the wave
PAUSE SOUND 5
' wait for 1 second
SLEEP 500
' Resume the sound
PRINT "leu"
RESUME SOUND 5
' wait for 1 second
SLEEP 500
' pause the wave
PAUSE SOUND 5
' wait for 1 second
SLEEP 500

' Resume the sound
PRINT "ia!"
RESUME SOUND 5
' wait for 1 second
SLEEP 500
' stop the wave
STOP SOUND 5
WAIT KEY


Panning and Volume Control

Zoom! Did you just hear that car go past? It sounded like it was going 200 miles per hour. Wow! The sounds you hear in everyday life move from left to right and change volume all the time. That is how you can tell where the sound is coming from and where it is going.

Panning represents the amount of sound coming from the left and right speakers. Something panned left will come completely from the left speaker.

Using the Panning and Volume Control Commands

Playing with the panning, speed, and volume in DarkBASIC is very easy. Setting a sound's panning requires only a simple command. Another command allows you to speed up the sound. Let's have some fun playing with sound effects.

The SET SOUND PAN Command

The SET SOUND PAN command places a sound effect somewhere between the two speakers. The values for SET SOUND PAN range from −100 to 100. −100 locates a sound effect on the left speaker; 100 locates it on the right speaker. Anywhere between −100 and 100 locates a sound effect on both the left and right speakers. The syntax for this command is

SET SOUND PAN Sound Number, Pan Value

Here are a few examples of the SET SOUND PAN command:

SET SOUND PAN 5, 100
SET SOUND PAN 1, -50

The GET SOUND PAN Command

The GET SOUND PAN command returns the current pan value. This lets you know where in the speakers your sound is playing. The syntax for this command is

GET SOUND PAN (Sound Number)

The Get Pan program uses the SET SOUND PAN and GET SOUND PAN commands. Figure 13.4 displays the output of the program.

click to expand
Figure 13.4: The Get Pan program demonstrates the GET SOUND PAN and SET SOUND PAN commands.


REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Get Pan program
---------------------------------

REMEND
' Plan sound effect from left to right
' Loads the talking wave
LOAD SOUND "talking.wav", 5
' Start looping the talking wave
PLAY SOUND 5
' Start a LOOP
FOR count = -10000 to 10000 step 1000
 ' Wait 1/100 second
 SLEEP 100
 ' Pan sound over to the left
 SET SOUND PAN 5, count
 CLS
 ' Get the current Pan
 CurrentPan = GET SOUND PAN(5)
 tempstring$ = "Current Pan = "+STR$(CurrentPan)
 PRINT tempstring$
NEXT count
WAIT KEY

The SET SOUND SPEED Command

The SET SOUND SPEED command changes a sound's playback frequency. Just like when you play a micro cassette recorder and speed up the playback, SET SOUND SPEED allows you to adjust the speed of a sound effect. My favorite effect is to turn my voice into the voice of one of the Chipmunks. This syntax for this command is

SET SOUND SPEED Sound Number, Frequency Value

Here are a few examples of the SET SOUND SPEED command:

SET SOUND SPEED 5 , 75000
SET SOUND SPEED 5 , 45000
SET SOUND SPEED 5 , 15000

The GET SOUND SPEED Command

The GET SOUND SPEED command returns the current playback speed of a sound, which lets you know how fast your sound is playing. The syntax for this command is

GET SOUND SPEED(Sound Number)

The Get Speed program uses the SET SOUND SPEED and GET SOUND SPEED commands. Figure 13.5 displays the output of the program.

click to expand
Figure 13.5: The Get Speed program demonstrates the GET SOUND SPEED and SET SOUND SPEED commands.

REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Get Speed program
---------------------------------
REMEND
' Loads the talking wave
LOAD SOUND "talking.wav", 5
SET SOUND SPEED 5 , 75000
' Play the talking wave
PLAY SOUND 5
' Get the current Pan
CurrentSpeed = GET SOUND SPEED(5)
' what's our current pan
PRINT CurrentSpeed
WAIT KEY

The SET SOUND VOLUME Command

The SET SOUND VOLUME command adjusts the volume of a sound effect. Volume is a very powerful thing. You can use it to tell the force of a punch or the caliber of a shot fired. The SET SOUND VOLUME command is DarkBASIC's volume control knob. The value to be set can be between 0 and 100 percent. The syntax for this command is

SET SOUND VOLUME Sound Number, Volume Value

Here are a few examples of the SET SOUND VOLUME command:

SET SOUND VOLUME 3 , 75
SET SOUND VOLUME 4 , 50
SET SOUND VOLUME 5 , 100

The GET SOUND VOLUME Command

The GET SOUND VOLUME command returns the volume of a sound effect, which you could use to determine the strength of a punch. The syntax for this command is

GET SOUND VOLUME(Sound Number)

The Get Volume program uses the SET SOUND VOLUME and GET SOUND VOLUME commands. Figure 13.6 displays the output of the program.

click to expand
Figure 13.6: The Get Volume program demonstrates the GET SOUND VOLUME and SET SOUND VOLUME commands.


REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Get Volume program
---------------------------------
REMEND
LOAD SOUND "talking.wav", 5
' Set's the volume to 75 percent
SET SOUND VOLUME 5 , 75
' Play the talking wave
PLAY SOUND 5
' Get the current Pan
CurrentVolume = GET SOUND VOLUME(5)
' what's our current pan
PRINT CurrentVolume


Sound Properties

Now you come to one of the more interesting parts of sound management—sound properties. These tell you the type of sound you are listening to and whether it is playing or paused.

Retrieving Sound Properties

Retrieving sound properties is a snap in DarkBASIC. All of the commands return a 1 or a 0 to let you know the information for which you are looking. There are three sound property commands—SOUND TYPE, SOUND PLAYING, and SOUND PAUSED.

The SOUND TYPE Command

The SOUND TYPE command reports the type of sound loaded in the buffer. There are two different types of sounds that can be loaded—normal sounds and 3D sounds. If SOUND TYPE returns a 0, the sound effect in question is a normal sound; if it returns a 1, the sound effect in question is a 3D sound. The syntax for this command is

SOUND TYPE(Sound Number)

Here are some examples of the SOUND TYPE command:

SoundType = SOUND TYPE(5)
SoundType = SOUND TYPE(6)

The SOUND PLAYING Command

The SOUND PLAYING command reports whether a sound is playing. This can be useful when a sound needs to be played through completely before continuing. The syntax for this command is

SOUND PLAYING (Sound Number)

Here are a couple examples of the SOUND PLAYING command:

IsSoundPlaying = SOUND PLAYING(5)
IsSoundPlaying = SOUND PLAYING(6)

The SOUND PAUSED Command

The SOUND PAUSED command reports whether a sound is paused. This allows you complete control over the playback of the sound. The syntax for this command is

SOUND PAUSED(Sound Number)

Here are a few examples of the SOUND PAUSED command:

SoundIsPaused = SOUND PAUSED(5)
SoundIsPaused = SOUND PAUSED(6)


Positional Sound

Drip, drip, drip…. My first experience with good positional sound was while watching Jurassic Park. I remember being engrossed in the action of the movie when I noticed something. Rain—it sounded as though it was raining outside. But it shouldn't be raining in the middle of the summer! Then I realized that it was the movie. The rain completely permeated the room so that it sounded like it was raining outside the theater! What an amazing feeling that was, listening to the sounds around me and being completely fooled like that.

Positional sound is known by many names, including Dolby Digital DTS, surround sound, and four-way sound. It is any sound that incorporates more than two-directional sound (left and right). Can you have positional sound with just two speakers? Using panning, speed, and volume tricks, two speakers can make a sound seem to be behind you or in front of you—so yes, even two speakers can reproduce positional sound.

Using Positional Sound

DarkBASIC incorporates some of the latest technology available to DirectSound to use positional sound. DirectSound 3D sounds will work on anything from two speakers to a full-blown Dolby Digital system. DirectSound allows you to position sound effects anywhere in a virtual room. That's not all, though—it also lets you position the user in the room. So you can sit in your chair and be moved in a whirlwind effect around a room of sound.

Sound Source Positioning

Planning is key in positional sound. You must keep track of where you are and where your sound is in the virtual room. Confusion will set in if you're hit in the front left of the virtual room and the sound comes from the back right.

Positioning a sound is a simple process in DarkBASIC. First you load a sound effect as a 3D sound, and then you use the POSITION SOUND command to position it. Finally, you play the sound effect.

The POSITION SOUND Command

POSITION SOUND is the most important command for the 3D positioning of a sound effect. It takes a sound effect and positions it in a 3D room. For more information on the fundamentals of 3D, see Chapter 17, "Fundamentals of 3D Graphics Programming." The syntax for this command is

POSITION SOUND Sound Number, X position, Y position, Z position

Here are a few examples of the POSITION SOUND command:

POSITION SOUND 5, 700,50,500
POSITION SOUND 6, -20,45,-40

The SOUND POSITION X Command

The SOUND POSITION X command returns the location of the sound effect on the X plane. The syntax for this command is

SOUND POSITION X(Sound Number)

Here are a few examples of the SOUND POSITION X command:

tempstring$ = "X pos = "+STR$(SOUND POSITION X(5))
xpos = SOUND POSITION X(6)

The SOUND POSITION Y Command

The SOUND POSITION Y command returns the location of the sound effect on the Y plane. The syntax for this command is

SOUND POSITION Y(Sound Number)

Here are a few examples of the SOUND POSITION Y command:

tempstring$ = "Y pos = "+STR$(SOUND POSITION Y(5))
ypos = SOUND POSITION Y(6)

The SOUND POSITION Z Command

The SOUND POSITION Z command returns the location of the sound effect on the Z plane. The syntax for this command is

SOUND POSITION Z(Sound Number)

The Sound Position program shows you how to use the POSITION SOUND, SOUND POSITION X, SOUND POSITION Y, and SOUND POSITION Z commands. Figure 13.7 shows the output of this program.

click to expand
Figure 13.7: The Sound Position program demonstrates the effects of the sound positioning commands.

REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Sound Position program
---------------------------------
REMEND
' Loading the sound effect
LOAD 3DSOUND "beep.wav", 6
' Lets put the sound in front and to the right of us
POSITION SOUND 6, 700,50,500
' Play the sound
PLAY SOUND 6
' Print the X position
tempstring$ = "X pos = "+STR$(SOUND POSITION X(6))
PRINT tempstring$
tempstring$ = "Y pos = "+STR$(SOUND POSITION Y(6))
PRINT tempstring$
tempstring$ = "Z pos = "+STR$(SOUND POSITION Z(6))
PRINT tempstring$

Listener Positioning

The sound effects are now placed in the room. Who is listening to them? What if this listener turns around? Would that reposition all the sound effects? Not really. The sound effects would be in the same locations as they were before, but the listener's orientation would be different.

In DarkBASIC, it is just as easy to orient the listener as it is to move all the sounds. There are two key commands to orient the listener to the positions of the sounds. I try to place the sounds in the room as if the listener were in the center of the room, facing forward. Then I rotate the listener.

The POSITION LISTENER Command

The POSITION LISTENER command places the listener somewhere in the virtual room. This affects the audible location of the sound based on where the listener is located. The syntax for this command is

POSITION LISTENER X position, Y position, Z position

Here are a few examples of the POSITION LISTENER command:

POSITION LISTENER 300,0,10
POSITION LISTENER 40,-50,-3

The LISTENER POSITION X Command

The LISTENER POSITION X command returns the listener's X position. The syntax for this command is

LISTENER POSITION X()

Here are a few examples of the LISTENER POSITION X command:

tempstring$ = "Listener X pos = "+STR$(LISTENER POSITION X())
ListenerX = LISTENER POSITION X()

The LISTENER POSITION Y Command

The LISTENER POSITION Y command returns the listener's Y position. The syntax for this command is

LISTENER POSITION Y()

Here are a few examples of the LISTENER POSITION Y command:

temptring$ = "Listener Y pos = "+STR$(LISTENER POSITION Y())
ListenerY = LISTENER POSITION Y()

The LISTENER POSITION Z Command

The LISTENER POSITION Z command returns the listener's Z position. The syntax for this command is

LISTENER POSITION Z()

The Listener Position program shows you how to use the POSITION LISTENER, LISTENER POSITION X, LISTENER POSITION Y, and LISTENER POSITION Z commands. Figure 13.8 show the output of this program.

click to expand
Figure 13.8: The Listener Position program demonstrates the LISTENER POSITION commands.

REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Listener Position program
---------------------------------
REMEND
' Loading the sound effect
LOAD 3DSOUND "beep.wav", 6
' Lets put the sound in front and to the right of us
POSITION SOUND 6, 100,0,10
' Lets put the listener to the right of the sound.
' So the sound is to the left of the listener
POSITION LISTENER 300,0,10
' Play the sound
PLAY SOUND 6
tempstring$ = "Listener X pos = "+STR$(LISTENER POSITION X())
' Locate The X position of the listener
PRINT tempstring$
' Locate The Y position of the listener
tempstring$ = "Listener Y pos = "+STR$(LISTENER POSITION Y())
PRINT tempstring$
' Locate The Z position of the listener
tempstring$ = "Listener Z pos = "+STR$(LISTENER POSITION Z())
PRINT tempstring$
WAIT KEY

The ROTATE LISTENER Command

The ROTATE LISTENER command faces the listener in the correct direction, which also affects the audible location of the sounds. The sound might be to the right of the listener, but if the listener is facing the sound, it is then in front of him. The syntax for this command is

ROTATE LISTENER X angle, Y angle, Z angle

Here are a few examples of the ROTATE LISTENER command:

ROTATE LISTENER 0,0,45
ROTATE LISTENER 30,15,15

The LISTENER ANGLE X Command

The LISTENER ANGLE X command returns the X angle of the listener direction. The command syntax is

LISTENER ANGLE X()

Here are a few examples of the LISTENER ANGLE X command:

temptring$ = "Listener X angle = "+STR$(LISTENER ANGLE X())
xangle = LISTENER ANGLE X()

The LISTENER ANGLE Y Command

The LISTENER ANGLE Y command returns the Y angle of the listener direction. The syntax for this command is

LISTENER ANGLE Y()

Here are a few examples of the LISTENER ANGLE Y command:

tempstring$ = "Listener Y angle = "+STR$(LISTENER ANGLE Y())
yangle = LISTENER ANGLE Y()

The LISTENER ANGLE Z Command

The LISTENER ANGLE Z command returns the Z angle of the listener direction. The syntax for this command is

LISTENER ANGLE Z()

The Listener Angle program shows you how to use the ROTATE LISTENER, LISTENER ANGLE X, LISTENER ANGLE Y, and LISTENER ANGLE Z commands. Figure 13.9 shows the output of this program.

click to expand
Figure 13.9: Output from the Listener Angle program

REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - Listener Angle program
---------------------------------
REMEND
' Loading the sound effect
LOAD 3DSOUND "beep.wav", 6
' Lets put the sound in front and to the right of us
POSITION SOUND 6, 100,0,10
' Lets put the listener to the right of the sound.
' So the sound is to the left of the listener
POSITION LISTENER 300,0,10
' Play the sound
LOOP SOUND 6
' Lets rotate the listener around
FOR zang = 1 to 360 step 10
 ROTATE LISTENER 0,0,zang
 ' Locate The X angle of the listener
 tempstring$ = "Listener X angle = "+STR$(LISTENER ANGLE X())
 PRINT tempstring$;
 ' Locate The Y angle of the listener
 tempstring$ = " Y angle = "+STR$(LISTENER ANGLE Y())
 PRINT tempstring$;
 ' Locate The Z angle of the listener
 tempstring$ = " Z angle = "+STR$(LISTENER ANGLE Z())
 PRINT tempstring$
 SLEEP 100
NEXT zang
WAIT KEY


Project The AudioMatch Game

Wow, there are a lot of commands to control sound in DarkBASIC. You covered 33 different sound commands in this chapter! Now you are going to put them to use. I have written a simple game that uses the sound effects commands in a creative way.

I've written a particular game for every programming language that I have learned over the years—a matching game. I have created one in Pascal, C, Visual Basic, Lingo (Director), and even for a Pocket PC. So I thought, why not take the matching game to the next level? Thus AudioMatch was born. It's an interesting twist on the tile-matching theme, but rather than using graphics, this game requires the player to match sound effects! Pretty neat idea, don't you think?

The premise of AudioMatch is simple. Just match two sounds by clicking on cards that appear on the screen. There are 25 sounds to choose from, and you won't know where they are because the game randomizes the sounds every time. You have to click a card to hear the sound. Figure 13.10 shows what the AudioMatch game looks like.

click to expand
Figure 13.10: The AudioMatch game

I created all of the sound effects in this game. (It is not easy to record your own voice without laughing!) All the sounds are located in the level01 sounds directory. This game includes a title screen and a winning screen. The only way to lose is to give up and go to the next chapter.

  Note

For the record, and just so at least one of us retains his reputation as a stark professional, that's Joshua's voice!

REMSTART
---------------------------------
Beginner's Guide To Game Programming With DarkBASIC
Copyright (C)2002 Jonathan S. Harbour and Joshua R. Smith
Chapter 13 - AudioMatch
---------------------------------
REMEND

REMSTART
 Image Data
 IMAGE 1 - Card Close
 IMAGE 2 - Card Selected
 IMAGE 3 - Mouse cursor
 IMAGE 4 - Title IMAGE
 IMAGE 5 - Win
 IMAGE Sprite USAGE
 SPRITE 10 - mouse Cursor
 SPRITES 50-99 - Matching cards
 Sound USAGE
 SOUNDS 50-75 - Sounds To Match
 SOUND 13 - Match Found
 SOUND 14 - Match Not Found
REMEND

DATA "level01/123.wav"
DATA "level01/abc.wav"
DATA "level01/ardvark.wav"
DATA "level01/baa.wav"
DATA "level01/bark.wav"
DATA "level01/basic.wav"
DATA "level01/boom.wav"
DATA "level01/clunk.wav"
DATA "level01/cool.wav"
DATA "level01/Dark.wav"
DATA "level01/eek.wav"
DATA "level01/eieio.wav"
DATA "level01/HadAFarm.wav"
DATA "level01/hehehe.wav"
DATA "level01/horse.wav"
DATA "level01/meow.wav"
DATA "level01/moo.wav"
DATA "level01/oink.wav"
DATA "level01/OldMac.wav"
DATA "level01/quack.wav"
DATA "level01/roar.wav"
DATA "level01/squeek.wav"
DATA "level01/wee.wav"
DATA "level01/wild.wav"
DATA "level01/woof.wav"

' Dim all global Variables
DIM LevelData(50)
' 1 stores current match
' 2 stores first match
' 3 stores second match
' 4 stores total guesses
' 5 stores the number of matches
DIM Selections(5)
SYNC OFF
SYNC RATE 30

MainTitle()
LoadSounds()
SYNC
PlayLevel()
END

' Loads all the sounds
FUNCTION LoadSounds()
 ' Load Sounds
 FOR count = 50 TO 74
 READ WaveFile$
 LOAD 3DSOUND WaveFile$, count
 ' Randomly position it in the world
 POSITION SOUND count, rnd(100), rnd(100), rnd(100)
 NEXT count

 ' Place the listener in the virutal world
 POSITION LISTENER 0,0,0
 ROTATE LISTENER 0,0,0

 LOAD SOUND "yeah.wav", 13
 LOAD SOUND "bummer.wav", 14
ENDFUNCTION

' Setup the level
FUNCTION SetupLevel()
 ' Randomize the Sounds
 RandomSeed = TIMER()
 RANDOMIZE RandomSeed

 FOR count = 1 TO 50
 LevelData(count) = 0
 NEXT count

 slotpicked = RND(49)+1
 count2 = 0
 FOR count = 50 TO 99
 WHILE LevelData(slotpicked) > 0
 slotpicked = rnd(49)+1
 ENDWHILE
 LevelData(slotpicked) = count
 NEXT count

 FOR count = 1 TO 50
 IF LevelData(count) > 74
 LevelData(count) = LevelData(count) - 25
 ENDIF
 NEXT count

 ' Load the images
 LOAD IMAGE "card.bmp", 1
 LOAD IMAGE "cardselect.bmp", 2
 LOAD IMAGE "cursor.bmp",3
 ' Centering the cards on the X ROW - Start at 120
 ' Centering the cards on the Y ROW - start at 40
 FOR ypos = 0 TO 4
 FOR xpos = 0 TO 9
 spritenum = 50+(ypos*10)+xpos
 spritex = 40 + (xpos*56)
 spritey = 40+ (ypos*56)
 SPRITE spritenum, spritex, spritey, 1
 NEXT xpos
 NEXT ypos

 ' Set up Mouse
 HIDE MOUSE
 SPRITE 10, MOUSEX(), MOUSEY(), 3
 SHOW ALL SPRITES
 ' Set up Selection Variables
 Selections(1) = 0
 Selections(2) = 0
 Selections(3) = 0
 Selections(4) = 0
 Selections(5) = 0
ENDFUNCTION

' Main Game Loop
FUNCTION PlayLevel()
 SetupLevel()
 Flag = 0
 SYNC
 WHILE Flag = 0
 ProcessMouse()
 ProcessClicks()
 ProcessMatches()
 DoWin = ProcessWins()
 IF DoWin=1
 SLEEP 500
 PlayAgain = DoTheWinScreen()
 IF PlayAgain=1
 SetupLevel()
 ELSE
 Flag = 1
 ENDIF
 ENDIF
 SYNC
 ENDWHILE
ENDFUNCTION

' Process the mouse cursor
FUNCTION ProcessMouse()
 SPRITE 10, MOUSEX(), MOUSEY(), 3
ENDFUNCTION

' Process Mouse clicks
FUNCTION ProcessClicks()
 IF MOUSECLICK() <> 1 THEN EXITFUNCTION
 cardselected = SPRITE COLLISION(10,0)
 ' Not over a card
 IF cardselected = 0 THEN EXITFUNCTION
 IF cardselected = Selections(2) THEN EXITFUNCTION
 IF cardselected = Selections(3) THEN EXITFUNCTION
 IF SOUND PLAYING(13) THEN EXITFUNCTION
 IF SOUND PLAYING(14) THEN EXITFUNCTION
 FirstSelected = Selections(2) - 49
 SecondSelected = Selections(3) - 49

 Spx = SPRITE X(cardselected)
 Spy = SPRITE Y(cardselected)
 SPRITE cardselected, Spx, Spy, 2
 Selections(1) = Selections(1) + 1
 ' Increament it by 1 to pass the Selections(1) info
 CurrentSelect = Selections(1) + 1
 Selections(CurrentSelect) = cardselected
 cardselected = cardselected - 49
 PLAY SOUND LevelData(cardselected)
ENDFUNCTION

' Check for matches
FUNCTION ProcessMatches()
 MySel1 = Selections(1)
 MySel2 = Selections(2)
 MySel3 = Selections(3)
 IF MySel1 = 2
 SLEEP 500
 IF LevelData(MySel2-49) = LevelData(MySel3-49)
 SPRITE MySel2,-100,-100,1
 SPRITE MySel3,-100,-100,1
 PLAY SOUND 13
 Selections(5) = Selections(5) + 1
 ELSE
 SPRITE MySel2, SPRITE X(MySel2),SPRITE Y(MySel2), 1
 SPRITE MySel3, SPRITE X(MySel3),SPRITE Y(MySel3), 1
 PLAY SOUND 14
 ENDIF
 Selections(1) = 0
 Selections(2) = 0
 Selections(3) = 0
 Selections(4) = Selections(4) + 1
 ENDIF
ENDFUNCTION

' Check to see if they've won
FUNCTION ProcessWins()
 Flag = 0
 IF Selections(5) >= 25 THEN Flag = 1
ENDFUNCTION Flag

FUNCTION MainTitle()
 LOAD IMAGE "title.bmp",4
 PASTE IMAGE 4,0,0
 SYNC
 WHILE (MOUSECLICK() = 0)
 ENDWHILE
 DELETE IMAGE 4
 CLS
ENDFUNCTION

'307,184 -- Print number of tries
'386,313 to -- The Y of the Y/N
' 414,347
FUNCTION DoTheWinScreen()
 HIDE ALL SPRITES
 SLEEP 2000
 SHOW MOUSE
 Flag = 0
 LOAD IMAGE "win.bmp",5
 PASTE IMAGE 5,0,0
 SET CURSOR 307, 184
 PRINT selections(4)
 SYNC
 WHILE (MOUSECLICK() = 0)
 ENDWHILE
 mx = MOUSEX()
 my = MOUSEY()
 IF mx >386 AND mx <414 AND my >313 AND my<347 THEN Flag = 1
 CLS
ENDFUNCTION Flag

This project is pretty extensive, but you will be surprised to find out that it only consists of 210 lines of code. That's pretty interesting, considering what it does. There are many more things that you could do with this game. Here is a list of a few improvements that you might want to add on your own:

  • Include multiple levels (using more then one set of data).
  • Keep track of a high score (possibly per level).
  • Add a timer to pressure the player to play faster.
  • Add a picture for each card when it is turned over.
  • Add a background picture that is displayed as the cards are matched.
  • Animate the cards.


Summary

This chapter covered all of the sound effects commands in DarkBASIC. There are quite a few of them. Sound effects are essential when you are creating games that have dynamic output because sound helps the player become immersed in the game. Without good sound effects, the overall game experience is diminished. (As you will learn in Chapter 14, "Playing Some Tunes: CD Audio, MIDI, and MP3 Music," music also plays a big part.) Along with killer graphics, powerful sound effects and music are essential ingredients for a perfect game.


Quiz

The chapter quiz will help reinforce the material you learned in this chapter, as well as provide feedback on how well you have learned the subjects that were covered. For the answers to the quiz, refer to Appendix A, "Answers to the Chapter Quizzes."

1.

Which function loads a sound?

  1. LOAD SOUND
  2. PLAY SOUND
  3. POSITION SOUND
  4. PAUSE SOUND

a

2.

Which function removes a sound from memory?

  1. PLAY SOUND
  2. POSITION SOUND
  3. DELETE SOUND
  4. CLONE SOUND

c

3.

Which is the correct way to load a 3D sound?

  1. LOAD SOUND "beep.wav", 5
  2. CLONE SOUND 6,5
  3. PAUSE SOUND 7
  4. LOAD 3DSOUND "beep.wav", 5

d

4.

What does the SOUND PLAYING function do?

  1. Deletes a sound
  2. Reports whether a sound is playing
  3. Positions a sound
  4. Plays a sound

b

5.

LOOP SOUND only plays a sound once.

  1. True
  2. False

b

6.

What is the correct way to stop a sound?

  1. LOAD SOUND
  2. POSITION SOUND
  3. STOP SOUND
  4. RESUME SOUND

c

7.

In the command POSITION SOUND 6, 100, 150, 300, what is the X position of the sound?

  1. 6
  2. 100
  3. 150
  4. 300

b

8.

What is the proper way to get the X position of a sound that has been positioned by POSITION SOUND 6, 100, 150, 300?

  1. SOUND POSITION X(6)
  2. SOUND POSITION X(100)
  3. SOUND POSITION Y(6)
  4. SOUND POSITION X(150)

a

9.

What is the proper way to set the speed of sound 8 to 600?

  1. SET SOUND SPEED 600,8
  2. SET SOUND SPEED 8,600
  3. SET SOUND PAN 600,8
  4. SET SOUND PAN 8,600

b

10.

Why would you use the RESUME SOUND command?

  1. To start a sound
  2. To load a sound
  3. To resume playing a sound
  4. To delete a sound

c

Answers

1.

A

2.

C

3.

D

4.

B

5.

B

6.

C

7.

B

8.

A

9.

B

10.

C




Beginner's Guide to DarkBASIC Game Programming
Beginners Guide to DarkBASIC Game Programming (Premier Press Game Development)
ISBN: 1592000096
EAN: 2147483647
Year: 2002
Pages: 203

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