6.5. Методика приостановки и возобновления звуков на основе встроенного ресурса
Для приостановки и возобновления воспроизведения звуковых файлов во время выполнения приложения можно разработать много вариантов кода, например, воспользоваться каким-либо элементом управления или компонентом.
Так как далее для задания режимов почти всех игр мы будем применять выпадающее меню типа MenuStrip, то для решения поставленной здесь задачи применим это меню. С панели инструментов Toolbox переносим на форму элемент управления MenuStrip и щёлкаем по нему (ниже формы в режиме проектирования). На форме Form1 появляются окна с надписью Type Here (Печатайте здесь), в которые записываем команды на русском языке (по второму варианту, можно записывать в панели Properties в свойстве Text), для примера, для управления двумя звуковыми файлами: Звуки, Звук 1, Звук 2, рис. 6.8. Теперь в панели Properties в свойстве Name изменяем эти русские команды на соответствующие английские: Sounds, Sound1, Sound2. Рассмотрим первую команду Звук 1.
Рис. 6.8. Команды MenuStrip.
Щёлкаем по этой команде Звук 1 и в панели Properties (для этой команды) значение свойства Checked задаём как True, чтобы на форме слева от этой команды появился флажок. А чтобы этот флажок можно было удалить и снова установить (после щелчка по команде мышью), в панели Properties для этой команды значение свойства CheckOnClick также задаём как True.
Дважды щёлкаем по этой команде Звук 1 (в режиме проектирования). Появляется файл Form1.vb с автоматически сгенерированным шаблоном метода, выше которого объявляем булеву переменную, а в шаблон записываем код, как показано на следующем листинге.
Листинг 6.11. Код для приостановки и возобновления звука.
'Объявляем логическую переменную OffOn и задаём ей True:
Dim OffOn As Boolean = True
Private Sub Sound1ToolStripMenuItem_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Sound1ToolStripMenuItem.Click
'Изменяем значение на противоположное:
OffOn = Not OffOn
'Выключаем Stop и включаем Play звук 1:
If (OffOn = False) Then
winSound.StopSound()
Else
winSound.PlayLoop()
End If
End Sub
Теперь в режиме выполнения (Build, Build Selection; Debug, Start Without Debugging), поочерёдно удаляя или устанавливая мышью флажок напротив этой команды Звук 1, мы будем выключать методом StopSound и включать методом PlayLoop циклическое (Loop) непрерывное воспроизведение звукового файла, который мы добавили в проект.
Если после каждой установки флажка нам нужно воспроизводить звуковой файл только один раз, то вместо строки:
winSound.PlayLoop()
записываем (как уже было показано выше):
winSound.Play()
Аналогично можно использовать команду Звук 2 для управления вторым звуковым файлом. Аналогично по этой методике мы можем добавить в проект много звуковых файлов, а в меню MenuStrip много команд для приостановки и возобновления звукового сопровождения разнообразных игр (в режиме выполнения).
6.6. Вариант воспроизведения звуковых файлов на основе встроенного ресурса
Учитывая важность методики воспроизведения звуковых файлов на основе встроенного ресурса, которую можно применять в приложениях и для настольного компьютера, и для мобильного устройства, приведём второй вариант этой методики.
Основное отличие данного варианта от предыдущего заключается в том, что вместо объявления объектов класса Sound для каждого звукового файла (по первому варианту):
Dim moveSound As Sound
Dim winSound As Sound
мы объявляем динамические массивы (array) типа Byte для каждого звукового файла (по второму варианту):
Dim array_btSoundBounce() As Byte
Dim array_btSoundExplode() As Byte
Остальные пояснения будут понятны из нового проекта.
Для создания проекта в VS щёлкаем кнопку New Project (или File, New, Project). В панели New Project в окне Project Types выбираем тип проекта Visual Basic, Windows, в окне Templates выделяем шаблон Windows Forms Application, в окне Name записываем любое имя проекта, например, Sounds6 и щёлкаем OK. Создаётся проект, появляется форма Form1 (рис. 6.9) в режиме проектирования.
Рис. 6.9. Форма Form1 в режиме выполнения.
Проектируем (или оставляем по умолчанию) эту форму, как описано в параграфе Методика проектирования формы.
Для добавления звукового файла bounce.wav (типа удара) в проект, в меню Project выбираем Add Existing Item, в панели Add Existing Item в окне Files of type устанавливаем All Files, в окне "Look in" находим (например, в папке с загруженным из Интернета файлом) файл и щёлкаем кнопку Add (или дважды щёлкаем по имени файла). Этот файл мы увидим в панели Solution Explorer.
В панели Solution Explorer выделяем имя этого файла, а в панели Properties (для данного файла) в свойстве Build Action (Действие при построении) вместо заданного по умолчанию выбираем значение Embedded Resource (Встроенный ресурс).
Аналогично добавляем и встраиваем в проект второй файл explode.wav типа взрыва. Аналогично можно добавить и встроить в проект ещё много звуковых файлов, которые мы желаем послушать во время выполнения приложения или игры.
Открываем файл Form1.vb (например, так: File, Open, File) и вверху записываем директиву для подключения требуемого пространства имен:
Imports System.Reflection 'Для класса Assembly.
Напомним, что эту строку можно и не записывать, но тогда нам придётся перед каждым классом записывать эти пространства имён System.Reflection.
Теперь в панели Properties (для формы Form1) на вкладке Events дважды щёлкаем по имени события Load (Загрузка).
Появляется файл Form1.vb с шаблоном метода Form1_Load, который после записи нашего кода принимает следующий вид.
Листинг 6.12. Метод для загрузки и воспроизведения звуковых файлов.
'Объявляем динамические массивы array типа Byte
'для каждого звукового файла:
Dim array_btSoundBounce() As Byte
Dim array_btSoundExplode() As Byte
'Загружаем в проект файлы изображений и звуков по такой схеме:
'Создаём объект myAssembly класса Assembly и присваиваем ему
'ссылку на исполняемую сборку нашего приложения:
Dim myAssembly As Assembly = Assembly.GetExecutingAssembly()
'Создаём объект myAssemblyName
'класса System.Reflection.AssemblyName и присваиваем ему
'имя сборки, которое состоит из имени проекта,
'Version, Culture, PublicKeyToken:
Dim myAssemblyName As AssemblyName = myAssembly.GetName()
'Из имени сборки при помощи свойства Name
'выделяем имя проекта типа string:
Dim myName_of_project As String = myAssemblyName.Name
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'Загружаем звуковые файлы в массивы:
array_btSoundBounce = Sound.ReadBytesFromStream( _
myAssembly.GetManifestResourceStream( _
myName_of_project + "." + "bounce.wav"))
array_btSoundExplode = Sound.ReadBytesFromStream( _
myAssembly.GetManifestResourceStream( _
myName_of_project + "." + "explode.wav"))
'Воспроизводим звук удара объекта о границы формы:
Sound.Play(array_btSoundBounce)
'Воспроизводим звук взрыва объекта:
'Sound.Play(array_btSoundExplode)
End Sub
В панели Solution Explorer выполняем правый щелчок по имени проекта и в контекстном меню выбираем Add, New Item (или Project, Add New Item). В панели Add New Item выделяем шаблон Code File, в окне Name записываем имя Sound.vb и щёлкаем кнопку Add.
В проект (и в панель Solution Explorer) добавляется этот файл, открывается пустое окно редактирования кода, в которое записываем следующий код.
Листинг 6.13. Файл Sound.vb.
Imports System.IO 'Для класса Stream.
Public Class Sound
'Константы для управления воспроизведением звукового файла:
Const SND_SYNC = &H0
Const SND_ASYNC = &H1
Const SND_NODEFAULT = &H2
Const SND_MEMORY = &H4
Const SND_LOOP = &H8
Const SND_NOSTOP = &H10
'Из пространства имён System.Runtime.InteropServices
'импортируем библиотеку winmm.dll и
'объявляем функцию PlaySoundBytes этой библиотеки:
Private Declare Function PlaySoundBytes _
Lib "winmm.dll" Alias "PlaySound" (ByVal szSound() As Byte, _
ByVal hModule As IntPtr, ByVal dwFlags As Integer) As Integer
'Метод для считывания звукового файла:
Public Shared Function ReadBytesFromStream( _
ByRef strBytes As Stream) As Byte()
Dim btRetVal() As Byte
btRetVal = New Byte(strBytes.Length) {}
strBytes.Read(btRetVal, 0, Fix(strBytes.Length))
Return btRetVal
End Function
'Метод для разового воспроизведения звукового файла:
Public Shared Sub Play(ByRef btBytes() As Byte)
PlaySoundBytes(btBytes, IntPtr.Zero, _
SND_ASYNC Or SND_MEMORY)
End Sub
End Class
Этот файл Sound.vb можно использовать во многих приложениях и играх для воспроизведения звуковых файлов, добавляя его в проект по стандартной схеме Project, Add Existing Item.
В режиме выполнения (Build, Build Selection; Debug, Start Without Debugging) мы услышим соответствующее (одноразовое) воспроизведение звукового файла, который мы добавили или непосредственно в проект, или в нашу дополнительную папку Sounds проекта.
6.7. Методика воспроизведения звуковых файлов на основе DirectX
Теперь для воспроизведения звуков в приложениях и играх только для настольных компьютеров опишем методику на основе технологии DirectX, точнее, её компонента DirectSound в виде одноименного пространства имён Microsoft.DirectX.DirectSound. Сейчас, применительно к начальным главам по двухмерным играм, эту очень мощную методику мы опишем кратко, а более подробно эта методика будет описана в конце книги для трёхмерных игр.
Приступим к программной реализации воспроизведения звуковых файлов, для общности, в новом проекте.
Для создания проекта в VS щёлкаем кнопку New Project (или File, New, Project). В панели New Project в окне Project Types выбираем тип проекта Visual Basic, Windows, в окне Templates выделяем шаблон Windows Forms Application, в окне Name записываем любое имя проекта и щёлкаем OK. Создаётся проект, появляется форма Form1 (рис. 6.10) в режиме проектирования.
Рис. 6.10. Форма Form1 в режиме выполнения.
Проектируем (или оставляем по умолчанию) эту форму, как описано в параграфе Методика проектирования формы. Например, в панели Properties в свойстве Font оставляем по умолчанию или устанавливаем новый шрифт и его размер (Size). Чтобы изменить заголовок формы, в панели Properties в свойстве Text записываем (или вставляем из буфера обмена: правый щелчок, Paste) текст.
На форме размещаем (с панели Toolbox), для примера, две кнопки Button (Sound 1 и Sound 2). В панели Properties в свойстве Text записываем название каждой кнопки Sound &1 и Sound &2 с оператором &, который подчёркивает следующий за ним символ текста, что позволяет нам задействовать кнопку не только мышью, но и, удерживая нажатой клавишу Alt, нажатием клавиши с подчёркнутой буквой английского алфавита или цифрой (например, Alt+1).
На форме в режиме выполнения по умолчанию выделена первая кнопка. Но если мы желаем, чтобы в режиме выполнения на форме была выделена другая кнопка (чтобы нажимать её не только мышью, но и клавишей Enter), то в панели Properties (для Form1) в свойстве AcceptButton выбираем имя этой кнопки.
По варианту 1, для добавления звукового файла drumpad-crash.wav в проект, в меню Project выбираем Add Existing Item, в панели Add Existing Item в окне Files of type устанавливаем All Files, в окне "Look in" находим (в системной папке компьютера C, WINDOWS, Media или, например, в папке с загруженным из Интернета файлом) файл и щёлкаем кнопку Add (или дважды щёлкаем по имени файла). Этот файл мы увидим в панели Solution Explorer. Если мы дважды щёлкнем по этому файлу drumpad-crash.wav, то откроется проигрыватель Windows Media Player, и мы услышим в течение нескольких секунд звучание типа шуршания оркестровых металлических тарелок при воздействии на них металлической метелки.
Аналогично добавляем в проект второй файл drumpad-bass_drum.wav типа удара барабана.
Аналогично можно добавить в проект ещё много звуковых файлов, которые мы желаем послушать во время выполнения приложения или игры.
По второму, закомментированному далее в программе, варианту эти файлы мы не добавляем в проект, а копируем во внешнюю папку с именем, например, Sounds, запоминая путь к этой папке, начиная от локального диска, например, D.
В проекте создаём ссылку на тот компонент DirectX, который потребуется для приложения. Для этого в меню Project выбираем Add Reference, а в панели Add Reference на вкладке (.NET) компонент Microsoft.DirectX.DirectSound и щёлкаем OK. Если в панели Add Reference пользователь не увидит компонента Microsoft.DirectX.DirectSound, то ему следует с сайта корпорации Microsoft бесплатно загрузить последнюю версию DirectX SDK и стандартно установить на свой компьютер.
Открываем файл Form1.vb (например, так: File, Open, File) и вверху записываем директиву для подключения этого же пространства имён (которое мы добавили в виде ссылки):
Imports Microsoft.DirectX.DirectSound
Напомним, что эту строку можно и не записывать, но тогда нам придётся перед каждым классом записывать эти пространства имён Microsoft.DirectX.DirectSound.
Теперь в любом месте класса Form1 записываем следующий универсальный (для всех последующих приложений и игр) код для инициализации DirectX.
Листинг 6.14. Универсальный код.
'Параметр устр-ва в виде панели визуализации renderWindow
'класса Control из пространства имён System.Windows.Forms:
Dim renderWindow As Control
'Добавляем переменные для воспроизведения звуков:
'Устройство DeviceOfSound класса Device из DirectSound:
Dim DeviceOfSound As Microsoft.DirectX.DirectSound.Device
'Класс вторичного буфера SecondaryBuffer
'для нескольких звуковых объектов-файлов:
Dim mySound1 As SecondaryBuffer ' = Nothing по умолчанию.
Dim mySound2 As SecondaryBuffer ' = Nothing по умолчанию.
'Инициализируем и устанавливаем параметры DirectX:
Public Function InitializeDirectX() As Boolean
Try
'renderWindow связываем с this формой (или эл-м):
renderWindow = Me
'Создаём и инициализируем переменные для звука:
'Устройство DeviceOfSound класса Device из DirectSound:
DeviceOfSound = _
New Microsoft.DirectX.DirectSound.Device()
'Уровень доступа к устройству многозадачный Normal:
DeviceOfSound.SetCooperativeLevel(renderWindow, _
CooperativeLevel.Normal)
'Инициализация DirectX прошла успешно:
Return True
Catch
'Перехвачена ошибка инициализации DirectX:
Return False
End Try
End Function 'Конец метода InitializeDirectX.
Напомним, что именно этот универсальный код можно будет копировать и записывать в наши последующие приложения и игры (после нашего напоминания).
Теперь в панели Properties (для формы Form1)) на вкладке Events дважды щёлкаем по имени события Load (Загрузка).
Появляется файл Form1.vb с шаблоном метода Form1_Load, который после записи нашего кода принимает следующий вид.