forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Организация кода: вопросы хранения переменных (http://forum.boolean.name/showthread.php?t=14236)

Aikon 15.02.2011 00:20

Организация кода: вопросы хранения переменных
 
На каждом уровне игрока окружают свои звуки. Соответственно, для каждого звукового фрагмента приходится создавать одну/две глобальные переменные (звук/канал), чтобы можно было управлять ими. Однако, мне такой вариант не очень нравится, поскольку команду очистки уровня, придется модифицировать каждый раз.

В случае с графическими объектами, все решилось достаточно просто: создавая новый графический объект я его привязываю (назначаю Parent) к одному из заведомо существующих объектов (у меня их всего два - sceneMesh и scenePivot). Поэтому при очистке уровне достаточно вызвать
Код:

FreeEntity sceneMesh
FreeEntity scenePivot

Хотелось бы, что-то подобное для звука. Кажется через типы можно исхитрится. У кого какие идеи будут?

is.SarCasm 15.02.2011 00:34

Ответ: Организация кода: вопросы хранения переменных
 
Найди что нибудь с ООП

trion 15.02.2011 01:04

Ответ: Организация кода: вопросы хранения переменных
 
Ну тупо создай список со звуками

Код:

Type Snd
Field Hndl
End type

Загружай так:

Код:

LoadSnd.Snd = New Snd
LoadSnd\Hndl=LoadSound("snd.wav")

И присваивай своим глобальным переменным тот же звук

Код:

MySnd=LoadSnd\Hndl
и потом чтобы удалить сделаешь

Код:

For DelSnd.Snd=Each Snd
FreeSound DelSnd\Hndl
delete DelSnd
Next

тока учти, что в твоих глобальных переменных останутся идентификаторы звуков. Чисти вручную.

Но зато в списке будут зареганы все звуки.

Кстати вообще рекомендую делать менеджер не только звуков но и объектов также на списках. Так сможешь облегчить себе жизнь.

Aikon 15.02.2011 05:33

Ответ: Организация кода: вопросы хранения переменных
 
trion, спасибо. Воспользовался идеей, набросал небольшой менеджер для звуков :) Вроде неплохо получилось, прям не ожидал, что так просто будет.

Использование
Код:

Include "sound_manager.bb"
...
smLoadSound ("human_voice.mp3", "aaa")
smPlaySound ("aaa")
...
smDeleteAll()

sound_manager.bb
Код:

Type TSound
        Field Name$
        Field Sound
        Field Channel
        Field Volume
        Field Pitch
End Type

Function smSoundByName.TSound (name$)
        For snd.TSound = Each TSound
                If (snd\Name = name) Then Return snd
        Next
        DebugLog "Sound '" + name + "' is not exist!"
End Function
               
Function smLoadSound (filename$, name$, Volume = 100, Pitch = 0)
        snd.TSound = New TSound
        snd\Sound = LoadSound (filename)
        If (snd\Sound = -1) Then
                DebugLog "Sound '" + name + "' is not load!"
                Delete snd
        EndIf
        snd\Name = name
End Function

Function smPlaySound (name$)
        snd.TSound = smSoundByName (name)
        If snd <> Null Then
                If Not ChannelPlaying (snd\Channel) Then snd\Channel = PlaySound (snd\Sound)
        Else
                DebugLog "Sound '" + name + "' not found!"
        EndIf
End Function

Function smStopSound (name$)
        snd.TSound = smSoundByName (name)
        If snd <> Null Then
                StopChannel (snd\Channel)
        Else
                DebugLog "Sound '" + name + "' not found!"
        EndIf               
End Function

Function smDeleteAll ()
        For snd.TSound = Each TSound
                FreeSound snd\Sound
                Delete snd
        Next
End Function


trion 15.02.2011 06:31

Ответ: Организация кода: вопросы хранения переменных
 
Вполне! Только потом если оптимизировать будешь старайся уменьшать количество циклов такого типа (причем это касается не только звуков)
Код:

        For snd.TSound = Each TSound
                If (snd\Name = name) Then Return snd
        Next

Ведь ты можешь сразу при загрузке звуков получать прямой указатель строку в списке
Я пользуюсь Handle() и Object. () - как-то привык (эх помню времена, когда они вообще были недокументированными)
Вот переделал твой пример - БЕЗ цикла проверки при запуске звука (вот представь что у тебя тысячи звуков :)). То есть блитз это сделает своими более шустрыми механизмами. Почитай вроде в последних версиях справки про эти команды написано...

Код:

Include "sound_manager.bb"
...
aaa=smLoadSound ("human_voice.mp3")
smPlaySound (aaa)
...
smDeleteAll()


Код:

Type TSound
        Field Name$
        Field Sound
        Field Channel
        Field Volume
        Field Pitch
End Type

               
Function smLoadSound (filename$, name$="unknown", Volume = 100, Pitch = 0)
        snd.TSound = New TSound
        snd\Sound = LoadSound (filename)
        If (snd\Sound = -1) Then
                DebugLog "Sound '" + name + "' is not load!"
                Delete snd
        EndIf
        snd\Name = name
          Return Handle(snd) ; <<<<<<<<<<< (!)
End Function

Function smPlaySound (hndl)
        snd.TSound = Object.TSound(hndl) ; <<<<<<<<<<< (!)
        If snd <> Null Then
                If Not ChannelPlaying (snd\Channel) Then snd\Channel = PlaySound (snd\Sound)
        Else
                DebugLog "Sound '" + name + "' not found!"
        EndIf
End Function

Function smStopSound (hndl)
        snd.TSound = Object.TSound(hndl)  ; <<<<<<<<<<< (!)
        If snd <> Null Then
                StopChannel (snd\Channel)
        Else
                DebugLog "Sound '" + name + "' not found!"
        EndIf               
End Function

Function smDeleteAll ()
        For snd.TSound = Each TSound
                FreeSound snd\Sound
                Delete snd
        Next
End Function


Надеюсь не накосячил тут... Сам не компилил.

И еще желательно добавь проверку на одинаковые звуки при загрузке - чтобы память не засорять - то есть проверять есть ли такой звук в менеджере - если есть - то просто передавай этот хендл - правда не зубдь пометить его в списке так как при попытке стереть несуществующий звук выйдет ошибка. Но тут смотри сам по надобности.

Кстати - при загрузке отсутствующего звука ты получишь Object does not exist...
Код:

        snd.TSound = New TSound
        snd\Sound = LoadSound (filename)
        If (snd\Sound = -1) Then
                DebugLog "Sound '" + name + "' is not load!"
                Delete snd
        EndIf
        snd\Name = name ; <<<< Если отсутствует звук, то тут получишь ошибку - так как ты удалил уже snd выше в условии


PS. Параметр name$ - в принципе нафиг не нужен... Только если соберешься делать скриптовую систему или чего подобное...

Aikon 15.02.2011 17:14

Ответ: Организация кода: вопросы хранения переменных
 
trion, идея с Handle мне не понравилась: использование становится сложнее.
Идея с name заключается в том, что не надо создавать глобальные переменные и к звуковым фрагментам можно обращаться по имени.
Если мы используем имя, то код проигрывания определенного звука прост
Код:

smPlaySound ("aaa")
Если же Handle, то несколько сложнее
Код:

hdl = smSoundByName ("aaa")
smPlaySound (hdl)

Т.е. все равно выполнять цикл поиска.
Вообще насчет цикла я голову не забиваю: 100 звуковых фрагментов на уровень и то, вряд ли где можно услышать. Да и как я ранее уже говорил в другой теме - для меня Blitz3D это платформа для создания прототипа, т.е. быстро, убого, но играбельно, и поэтому выбирая между удобством написания кода и оптимизацией, следует выбирать первое.

P.S. Ага, косяк с удаляемым :)

Alex_Noc 16.02.2011 20:31

Ответ: Организация кода: вопросы хранения переменных
 
а приравнять просто переменную в 0 - не катит? На крайняк в нее грузить другой звук

trion 16.02.2011 22:36

Ответ: Организация кода: вопросы хранения переменных
 
Ну переменная хранит не звук, а ссылку на звук в памяти. Затрешь ссылку - звук в памяти и останется. Утечка памяти это совсем не клево.


Часовой пояс GMT +4, время: 18:12.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot