конструировании экземпляра класса, ведь изначально размер звукового файла неизвестен.
Код конструктора приведен в листинге 11.38.
/// <summary>
/// Создание экземпляра sound и хранение данных о звуке
/// </summary>
/// <param name='soundStream'>поток для чтения звука</param>
public Sound(Stream soundStream) {
 // создаем массив байтов для приема данных
 soundBytes = new byte[soundStream.Length];
 // читаем данные из потока
 soundStream.Read(soundBytes, 0, (int)soundStream.Length);
}
Поток связывается с файлом или другим источником данных. Он имеет свойство Length, определяющее размер массива. Метод Read применяется для получения информации, после чего прочитанные байты сохраняются в массиве. Звуковые файлы хранятся в виде ресурсов, как и изображения.
В проект надо добавить звуковые файлы click.wav и burp.wav и для их свойства Build Action задать значение Embedded Resources. Теперь доступ к звуковым файлам получить очень просто, что иллюстрирует код, приведенный в листинге 11.39.
/// <summary>
/// Звук, воспроизводимый при столкновении с батоном хлеба
/// </summary>
private Sound batHitSound;
/// <summary>
/// Звук, воспроизводимый при столкновении с помидором
/// </summary>
private Sound tomatoHitSound;
// Получим звук при столкновении с батоном хлеба
batHitSound = new Sound
 (execAssem.GetManifestResourceStream(@'Bouncer.click.wav'));
// Получим звук при столкновении с помидором
tomatoHitSound = new Sound
 (execAssem.GetManifestResourceStream(@'Bouncer.burp.wav'));
Для воспроизведения звука в класс Sound надо добавить метод Play, как показано в листинге 11.40.
/// <summary>
/// Управление звуком в игре (Включать или выключать)
/// </summary>
public static bool Enabled = true;
/// <summary>
/// Проигрываем звук
/// </summary>
public void Play() {
 if (Sound.Enabled) {
  WCE_PlaySoundBytes(soundBytes, IntPtr.Zero,
   (int)(Flags.SND_ASYNC | Flags.SND_MEMORY));
 }
}
Метод Play проверяет флаг переменной Enabled. С его помощью можно легко включать или выключать звук в игре. Воспроизведение звука обеспечивается вызовом функции Windows API WCE_PlaySoundBytes, что иллюстрирует код, приведенный в листинге 11.41.
private enum Flags {
 SND_SYNC = 0x0000,
 SND_ASYNC = 0x0001,
 SND_NODEFAULT = 0x0002,
 SND_MEMORY = 0x0004,
 SND_LOOP = 0x0008,
 SND_NOSTOP = 0x0010,
 SND_NOWAIT = 0x00002000,
 SND_ALIAS = 0x00010000,
 SND_ALIASID = 0x00110000,
 SND_FILENAME = 0x00020000,
 SND_RESOURCE = 0x00040004
}
/// <summary>
/// Функция Windows API для воспроизведения звука.
/// </summary>
/// <param name='szSound'>Массив байтов, содержащих данные /// </param>
/// <param name='hMod'>Дескриптор к модулю, содержащему звуковой
/// ресурс</param>
/// <param name='flags'>Флаги для управления звуком</param>
/// <returns></returns>
[DllImport('CoreDll.DLL', EntryPoint = 'PlaySound', SetLastError = true)]
private extern static int WCE_PlaySoundBytes( byte[] szSound,
 IntPtr hMod, int flags);
Теперь, когда создан экземпляр класса Sound, можно воспроизводить звук при столкновении сыра с батоном хлеба. Соответствующий код приведен в листинге 11.42.
// если сыр движется вниз
if (cheeseRectangle.IntersectsWith(breadRectangle)) {
 // столкновение
 // воспроизводим удар
 batHitSound.Play();
}
Можете запустить проект, чтобы проверить работу звука. Также можно добавить звук при столкновении сыра с помидорами. Этот код приведен в листинге 11.43.

 
                