скачать книгу бесплатно
End If
End Sub
Рис. 6.4. Команды MenuStrip.
Рис. 6.5. Задаём свойства команды.
Теперь в режиме выполнения (Build, Build Selection; Debug, Start Without Debugging), поочерёдно удаляя или устанавливая мышью флажок напротив этой команды “Звук 1”, мы будем выключать методом Stop и включать методом Play циклическое (Loop) непрерывное воспроизведение звукового файла, который мы добавили в проект.
Если после каждой установки флажка нам нужно воспроизводить звуковой файл только один раз, то вместо строки:
My.Computer.Audio.Play("..\..\drumpad-crash.wav", _
AudioPlayMode.BackgroundLoop)
записываем:
My.Computer.Audio.Play("..\..\drumpad-crash.wav")
Аналогично можно использовать команду “Звук 2” для управления вторым звуковым файлом.
Аналогично по этой методике мы можем добавить в проект много звуковых файлов, а в меню MenuStrip – много команд для приостановки и возобновления звукового сопровождения разнообразных игр (в режиме выполнения).
6.4. Методика воспроизведения звуковых файлов на основе встроенного ресурса
Недостатком предыдущей методики на основе пространства имён My является невозможность её использования для мобильных устройств (карманных компьютеров, коммуникаторов, смартфонов, мобильных телефонов и т.п.) с операционной системой Windows Mobile.
И среда выполнения .NET Framework для настольных компьютеров, и среда выполнения .NET Compact Framework для мобильных устройств позволяет записать неуправляемый код для воспроизведения звуковых файлов по методике встроенного ресурса (Embedded Resource) с использованием платформы Platform Invoke (сокращенно P/Invoke) и динамически подключаемой библиотеки (dynamic link library) winmm.dll (для настольного компьютера) или CoreDll.dll (для мобильного устройства) из более общей библиотеки Windows API (Application Programming Interfaces).
Данная универсальная методика на основе встроенного ресурса удобна при переносе какого-либо приложения (со звуковым сопровождением) с настольного компьютера на мобильное устройство и наоборот.
В данном параграфе мы разработаем универсальную методику воспроизведения звуковых файлов на основе нового файла Sound.vb, в котором имеется одноименный класс Sound.
Мы назвали эту методику универсальной потому, что она может быть применена во многих самых разнообразных играх, и далее будет нами применена в некоторых типичных играх.
В приложении класс Sound должен обеспечить:
выключение звука, если пользователь не желает его слушать;
непрерывный циклический звук;
одиночный звук.
Для каждого звука мы создаём объект класса Sound. Есть также несколько перегруженных конструкторов этого класса, чтобы мы могли создать объект при использовании внутреннего ресурса в виде пути к звуковому файлу filename или потока (Stream), как показано в следующем коде:
'Метод для считывания звукового файла:
Private Sub readStream(ByVal soundStream As Stream)
'Создаём массив soundBytes с элементами типа Byte
'и инициализируем размерность этого массива
'как длину звукового файла soundStream.Length:
soundBytes = New Byte(soundStream.Length) {}
'Из потока soundStream считываем звуковой файл
'в массив soundBytes:
soundStream.Read(soundBytes, 0, soundStream.Length)
End Sub
'Объявляем метод-конструктор класса Sound
'с параметром в виде потока soundStream класса Stream:
Public Sub New(ByVal soundStream As Stream)
'Вызываем метод для считывания звукового файла:
readStream(soundStream)
End Sub
'Объявляем метод-конструктор класса Sound
'с параметром в виде пути filename к звуковому файлу:
Public Sub New(ByVal filename As String)
Dim execAssem As System.Reflection.Assembly = _
System.Reflection.Assembly.GetExecutingAssembly()
Dim soundStream As Stream = _
execAssem.GetManifestResourceStream(filename)
If (soundStream Is Nothing) Then
System.Windows.Forms.MessageBox.Show( _
"Missing file : " + filename, "Audio Load")
Return
End If
readStream(soundStream)
End Sub
Метод readStream выполняет фактическую загрузку звука. Операционная система управляет звуком. Класс Sound использует платформу Platform Invoke (P/Invoke), чтобы при помощи этого метода вызвать и управлять звуком, как показано в следующем коде:
Public Enum Flags
SND_ALIAS = &H10000
SND_ALIAS_ID = &H110000
SND_FILENAME = &H20000
SND_RESOURCE = &H40004
SND_SYNC = &H0
SND_ASYNC = &H1
SND_NODEFAULT = &H2
SND_MEMORY = &H4
SND_LOOP = &H8
SND_NOSTOP = &H10
SND_NOWAIT = &H2000
SND_VALIDFLAGS = &H17201F
SND_RESERVED = &HFF000000
SND_TYPE_MASK = &H170007
End Enum
Private Declare Function PlaySound _
Lib "winmm.dll" Alias "PlaySound" (ByVal szSound() As Byte, _
ByVal hModule As IntPtr, ByVal dwFlags As Integer) As Integer
В этом коде ряд флажков (Flags) непосредственно управляет генерацией звука. Класс Sound содержит статический член, который в настоящее время имеет ссылку на непрерывный циклический звук (или любой другой). Если звук был выключен и затем снова включён, циклический звук возобновляется. Класс Sound содержит методы Play и PlayLoop для одиночного и циклического воспроизведения звукового файла, как показано в следующем коде:
'Метод для разового воспроизведения звукового файла:
Public Sub Play()
loopSound = Nothing
If (Sound.Enabled) Then
PlaySound(soundBytes, IntPtr.Zero, _
Fix(Flags.SND_ASYNC Or _
Flags.SND_MEMORY))
End If
End Sub
'Метод для циклического воспроизведения звукового файла:
Public Sub PlayLoop()
loopSound = soundBytes
If (Sound.Enabled) Then
PlaySound(soundBytes, IntPtr.Zero, _
Fix(Flags.SND_ASYNC Or _
Flags.SND_MEMORY Or _
Flags.SND_LOOP))
End If
End Sub
Метод StopSound в классе Sound останавливает проигрывающийся звук, задавая массиву soundBytes нулевое значение (Zero) следующим образом:
Public Sub StopSound()
If (Not loopSound Is Nothing) Then
PlaySound(Nothing, IntPtr.Zero, _
0)
End If
End Sub