Метод 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
}
///
/// Функция Windows API для воспроизведения звука.
///
/// Массив байтов, содержащих данные ///
/// Дескриптор к модулю, содержащему звуковой
/// ресурс
/// Флаги для управления звуком
///
[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.
if (cheeseRectangle.IntersectsWith(tomatoes[i].rectangle)) {
// воспроизводим звук столкновения сыра с помидором
tomatoHitSound.Play();
}
Дальнейшие улучшения
Но игру все еще можно улучшить. В следующем списке указаны дополнительные возможности, которые необходимо реализовать.
□ Режим «attract», включающийся, когда пользователь не играет.
□ Потеря жизни, если сыр ударился о нижнюю границу экрана.
□ При уничтожении всех томатов они должны появиться чуть ниже, и скорость игры должна возрасти.
□ Добавление в игру случайных элементов.
В программу надо ввести булеву переменную gameLive, которая имеет значение True, когда пользователь ведет игру. Если значение переменной равно False, то сыр будет двигаться по экрану, но никаких игровых действий производиться не будет.
Для этого потребуется изменить метод, выполняющийся при старте игры. Новая версия приведена в листинге 11.44.
///
/// True, если игра запущена на экране.
///
private bool gameLive = false;
///
/// Число оставшихся жизней.
///
private int livesLeft;
///
/// Число жизней, доступных для игрока.
///
private int startLives = 3;
private void startGame() {
// Устанавливаем число жизней, счет и сообщения
livesLeft = startLives;
scoreValue = 0;
messageString = "Счет: 0 Жизнь: " + livesLeft;
// Располагаем помидоры наверху экрана
tomatoDrawHeight = tomatoLevelStartHeight;
placeTomatoes();
// Поместим батон в центре экрана
breadRectangle.X = (this.ClientSize.Width - breadRectangle.Width) / 2;
breadRectangle.Y = this.ClientSize.Height / 2;
// Поместим сыр над батоном в центре экрана
cheeseRectangle.X = (this.ClientSize.Width - cheeseRectanglе.Width) / 2;
cheeseRectangle.Y = breadRectangle.Y — cheeseRectangle.Height;
// Установим начальную скорость
xSpeed = 1;
ySpeed = 1;
// Установим флаг, позволяющий начать игру
gameLive = true;
}