• No results found

lPaddleY = lPaddleY - (accelState.X * lPaddleSpeed);

}

When a process tries to enter a block of code protected by a lock it will try to grab hold of the lock object. If the object is not available the process will be made to wait for the lock to be released. This means that it is now not possible for one method to interrupt another. What will happen instead is that the first process to arrive at the block will get the lock object and the second process will have to wait until the lock is released before it can continue.

Locks provide a way of making sure that processes do not end up fighting over data. It is important that any code protected by a lock will complete quickly, so that other processes do not have to spend a lot of time waiting for access to the lock.

It is also important that we avoid what is called the “Deadly Embrace” problem where process A has obtained lock X and is waiting for lock Y, and process B has obtained lock Y and is waiting for lock X. We can help prevent this by making a process either a “producer” which generates data or a “consumer”

which uses data. If no processes are both consumers and producers it is unlikely that they will be stuck waiting for each other.

6.4 Adding sound to a game

We can make games much more interesting by adding sound effects to them. As far as XNA is concerned a sound in a game is just another form of game resource. There are two kinds of sounds in a game. There are sound effects which will accompany particular game events, for example the sound of a spaceship exploding when it is hit with a missile, and there is background music which plays underneath the gameplay.

Sound effects are loaded into the game as content. They start as WAV files and are stored in memory when the game runs. They are played instantly on request.

Music files can also be supplied as game content but are played by the media player.

Creating Sounds

There are many programs that can be used to prepare sound files for inclusion in games. A good one is the program called Audacity. This provides sound capture and editing facilities. It can also convert sound files between different formats and re-sample sounds to reduce the size of sound files. Audacity is a free download from http://audacity.sourceforge.net

This shows a sound sample being edited in Audacity.

Sound samples and content

As far as an XNA game is concerned, a sound is just another item of content. It can be added alongside other content items and stored and managed by the content manager.

Within the game the SoundEffect class is used to hold the sound items:

// Sound effects SoundEffect dingSound;

SoundEffect explodeSound;

These are loaded in the LoadContent method, as usual:

dingSound = Content.Load<SoundEffect>("ding");

explodeSound = Content.Load<SoundEffect>("explode");

A SoundEffect instance provides a Play method that triggers the playback of the sound:

if (ballRectangle.Intersects(rPaddleRectangle)) {

ballXSpeed = -ballXSpeed;

dingSound.Play();

}

This is the code that detects a collision of the bat with the ball. The ding sound effect is played when this happens. This is the simplest form of sound effect playback. The sound is made the instant the method is called. The program will continue running as the sound is played. Windows Phone can play multiple sound effects at the same time; the hardware supports up to 64 simultaneous sound channels.

Using the SoundEffectInstance class

The SoundEffect class is very easy to use. It is a great way of playing sounds quickly. A game does not have to worry about the sound once it has started playing. However, sometimes a game needs to do more than just play the sound to completion. Some sound effects have to be made to play repeatedly, change in pitch or move to the left or the right. To get this extra control over a sound a game can create a SoundEffectInstance value from a particular sound effect.

We can think of this as a handle onto a playing sound. For example we might want to create the sound of a continuously running engine. To do this we start with a SoundEffect which contains the sound sample.

SoundEffect engineSound;

This would be loaded from an item of content which contains the engine sound.

Next we need to declare a SoundEffectInstance variable:

SoundEffectInstance engineInstance;

We can ask a SoundEffect to give us a playable instance of the sound:

engineInstance = engineSound.CreateInstance();

Now we can all methods on this to control the sound playback of the sound effect instance:

Note that the program can stop and start the playback of the sound effect instance, which is not something that is possible with a simple sound effect. A game can also control the volume, pitch and pan of a sound effect instance:

engineInstance.Volume = 1; // volume ranges from 0 to 1 engineInstance.Pitch = 0; // pitch ranges from -1 to +1 // -1 – octave lower

// +1 – octave higher engineInstance.Pan = 0; // pan ranges from -1 to +1 // -1 – hard left

// +1 – hard right The program can also make a sound loop, i.e. play repeatedly:

engineInstance.IsLooped = true;

Finally a program can test the state of the sound playback:

if (engineInstance.State == SoundState.Stopped) {

engineInstance.Play();

}

This would start the sound playing again if it was stopped. Using a

SoundEffectInstance a game can make the pitch of the engine increase in frequency as the engine speeds up and even track the position of the car on the screen.

A SoundEffectInstance is implemented as a handle to a particular sound channel on the Windows Phone device itself. We have to be careful that we a game doesn‟t create a very large number of these because this might cause the phone to run out of sound channels.

The solution in Demo 07 Game with Sounds contains a Windows Phone XNA game that implements a working pong game with sound effects.