forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   2D-программирование (http://forum.boolean.name/forumdisplay.php?f=13)
-   -   Музыка (http://forum.boolean.name/showthread.php?t=95)

Dizels 18.09.2005 17:51

Вот у меня вопросик появился - сделать следущим образом:
есть папка - music, в ней храниться определенное количество файлов в .mp3 формате(количество меняеться!!!)Так вот, как сделать, чтобы Блитц открывал все что там есть, и проигрывал в случайном порядке?

alcosholik 18.09.2005 18:07

Тебе нужно посмотреть описание использования команды NextFile$ в хелпе или >здесь<.

impersonalis 18.09.2005 18:21

Код:

SeedRnd(MilliSecs())

Global music_channel%
;Global counter

Function SelectRandMusic(DIR$)
        Local counter%=0
        Local channel
        Local dir_h%=ReadDir(DIR$)
        While True
 *file$=NextFile$(dir_h)
 *If Upper$(Right(file$,3))="MP3"
 *        counter=counter+1
 *EndIf
 *If file$="" Exit
        Wend
        CloseDir dir_h
        Print "files="+counter
        Local iR%=Rand(1,counter%)
        If Not counter Return False
        counter=0
        dir_h%=ReadDir(DIR$)
        While True
 *file$=NextFile$(dir_h)
 *If Upper$(Right(file$,3))="MP3"
 *        counter=counter+1
 *        If counter%=iR
 * *Print "select - "+IR+" = "+file$
 * *channel=PlayMusic(DIR$+"\"+file$)
 *        Exit
 *        EndIf
 *EndIf
        Wend
        Return channel
End Function

SelectRandMusic("music")
While Not KeyHit(1)
Wend
End


Жека 20.09.2005 15:20

Замечание: если содержимое папки МЬЮЗИК меняется только ДО (после) запуска игры, то лучше сделать массив, в котором хранить ПУТИ к файлам и с ним работать (как путь найти impersonalis разъяснил выше).
А то перебирать ВСЕ файлы поновой, чтоб что-то выбрать....

impersonalis 20.09.2005 18:50

Цитата:

Originally posted by Жека@Sep 20 2005, 01:20 PM
Замечание: если содержимое папки МЬЮЗИК меняется только ДО (после) запуска игры, то лучше сделать массив, в котором хранить ПУТИ к файлам и с ним работать (как путь найти impersonalis разъяснил выше).
А то перебирать ВСЕ файлы поновой, чтоб что-то выбрать....

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

Жека 20.09.2005 19:12

Если файлов много, то возможны задержки при вызове функции.
Или нет?
Типы... Массив удобнее: PlayMysic (musicList$(Rand(MAX_KOLVO_MUSIC)))

Пусть Dizels использует типы, или весь твой код, а я буду массив! ;)

Diplomat 20.09.2005 21:44

Как насчет такого варианта.
Позволяет избежать тормозов в главном цикле цикле и знаменитых глюков команды PlayMusic за счет повышения времени загрузки. :)
Код:

Dir$="D:\KrutajaGama\Music"
CheckDir=ReadDir(Dir$)
File$="*"
NFiles=0
While File$<>""
  File$=NextFile$(CheckDir)
  If FileType(Dir$+"\"+File$) = 1 Then NFiles=NFiles+1
Wend
CloseDir CheckDir

Dim Music(NFiles)

CheckDir=ReadDir(Dir$)
File$="*"
NFile=0
While File$<>""
  File$=NextFile$(CheckDir)
  If FileType(Dir$+"\"+File$) = 1 Then Music(NFile)=LoadSound(Dir$+"\"+File$)
Wend
CloseDir CheckDir

While Not KeyHit(1)
  If ChannelPlaying(ChnlMusic)=0 then ChnlMusic=PlaySound(Music(Rnd(NFiles)))
Wend
End


Жека 20.09.2005 22:06

Diplomat, а сколько памяти ест музыка? Столько же, сколько на ХДД? Если у меня 20 треков, то это будет весить около 50-70 мб, и все это в память толкать?!

Не знаю как у вас, а у меня команда ChannelPlaying() тормозит, поэтому я вызываю ее 1 раз за 2-5 секунд, чаще смысла нет.
Тогда все ок, а если каждый раз при проходе цикла звать, то тормозит :(

Я массив так же "делаю", но вместо хендлов загоняю пути к файлам...

Diplomat 20.09.2005 22:21

Цитата:

это будет весить около 50-70 мб, и все это в память толкать?!
Да, плата за скорость работы и гарантию отсутствия глюков с PlayMusic на другой машине...:(
А насчет памяти- то 70 метров- это перегиб. Ну пусть 5 треков МР3- это 50Мб максимум... При обьеме оперативы в 1Гиг (ну или даже 256Мб) это условие перестает играть каку-либо роль... :ok:
Другое дело, что длинный трек может грузиться 1-5 секунд, а это уже серьезный недостаток... :unsure:

SubZer0 20.09.2005 22:23

Цитата:

Originally posted by Жека@Sep 20 2005, 08:06 PM
а сколько памяти ест музыка?
музыка подвергается раскодировке в нормальный для звуковой карты формат, а именно ADPCM wav... и проверить сколько это будет весить можно например виндосовским менеджером задач :)

jimon 20.09.2005 22:33

видимо воспроизводить потоково несудьба :o

SubZer0 20.09.2005 22:47

Цитата:

Originally posted by jimon@Sep 20 2005, 08:33 PM
видимо воспроизводить потоково несудьба :o
а ты что, хочешь, чтоб игра еще тормозила из-за раскодировки?? :) :)

по-моему было-бы глупо...

jimon 20.09.2005 23:17

мдя... когда ты слушаеш winamp (или че там еще) и устанавливаеш прогу , сидиш в аське , мучаеш paint :) то у тебя музычка тормозит ?!

есть такое заветное слово - буферизация :)

притом я же неговорил декодировать музыку в блице - для етого есть нормальные либы bass.dll например :))

SubZer0 20.09.2005 23:20

Цитата:

Originally posted by jimon@Sep 20 2005, 09:17 PM
когда ты слушаеш winamp (или че там еще) и устанавливаеш прогу , сидиш в аське , мучаеш paint :) то у тебя музычка тормозит ?!
а, ну да, если игрушка у тя такая, что кушает ресурсов меньше чем пайнт, то тогда я молчу... :down: :down:

jimon 21.09.2005 08:45

для раскодировки надо примерно 1-3 метра озу... может даже меньше (смотря какой буфер поставиш)

SubZer0 21.09.2005 15:43

Есть еще такая прога Cool Edit 2000 называется, я ей обычно смотрю, там когда файл открываешь, тыкаешь на название файла, а он тебе всю поднаготную о нем в том числе и размер в "распакованном" виде. :)

jimon 21.09.2005 17:07

вот непонимаю я тебя - зачем грузить весь файл в память ? может еще все текстуры игры загрузим в память а использовать будем только те что надо :o

ps. смотри атач

Dizels 22.09.2005 10:33

Я использовал код, который дал impersonalis, он меня вполне устраивает, но вот досада, файл выбираеться, потом играет, а вот после него тихо как в танке, а надо, чтобы следущий файл играл(тоже случайный).

Жека 22.09.2005 11:19

Тихо только в танке с выключенным двигателем!
С работающим - очень наоборот :)

С его кодом все нормально, ты присмотрись внимательнее к вызову команды PlayMusic, и обнаружишь переменную channel, в которую записан результат вызова плеймьюзик.
В главном цикле проверяешь состояние канала командой ChannelPlaying (channel). Если получаешь от нее НОЛЬ, то заново зовешь функцию SelectRandMusic

Еще сделай channel глобальной переменной.

Dizels 28.09.2005 11:10

Что-то у меня не получилось, подскажите:
Код:

SeedRnd(MilliSecs())

Global music_channel%
Global counter
Global channel
Function SelectRandMusic(DIR$)
Local counter%=0
Local channel
Local dir_h%=ReadDir(DIR$)
While True
 file$=NextFile$(dir_h)
 If Upper$(Right(file$,3))="MP3"
 counter=counter+1
 EndIf
 If file$="" Exit
Wend
CloseDir dir_h
Print "files="+counter
Local iR%=Rand(1,counter%)
If Not counter Return False
counter=0
dir_h%=ReadDir(DIR$)
While True
 file$=NextFile$(dir_h)
 If Upper$(Right(file$,3))="MP3"
 counter=counter+1
 If counter%=iR
  Print "select - "+IR+" = "+file$
  channel=PlayMusic(DIR$+"\"+file$)
 Exit
 EndIf
 EndIf
Wend
Return channel
End Function
ChannelPlaying (channel) If channel=0 Then
SelectRandMusic("music")

:@

Жека 28.09.2005 13:46

Вот рабочий пример:

Код:

SeedRnd(MilliSecs())

Global counter
Global channel


While Not (KeyHit (1))

If ChannelPlaying (channel) = 0 SelectRandMusic("music")

Wend

End


Function SelectRandMusic(DIR$)
Local counter%=0

Local dir_h%=ReadDir(DIR$)
While True
 file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
 counter=counter+1
EndIf
If file$="" Exit
Wend
CloseDir dir_h
Print "files="+counter
Local iR%=Rand(1,counter%)
If Not counter Return False
counter=0
dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
 counter=counter+1
 If counter%=iR
 Print "select - "+IR+" = "+file$
 channel=PlayMusic(DIR$+"\"+file$)
 Exit
 EndIf
EndIf
Wend
Return channel
End Function

Изменения:
1. Сделал проверку играет ли щас муза или нет, если нет, то заново запускаем
2. ЛОКАЛЬНУЮ переменную channel удалил к чертям! Значение локальных переменных ТЕРЯЕТСЯ при выходе из функции.

Dizels 28.09.2005 14:41

Все хорошо, вот только проблемка, теперь все играет, музыка меняеться, только вот игра не загружаеться:)Я end в начале убрал, но все равно проблема осталась!

impersonalis 28.09.2005 22:33

2 Жека:
channel Локальна в теле функции, но её значение возвращается через return - так что, ради каких чертей ты её убрал?
А вот юзание глобальных переменных ( ну уж по крайней мере - здесь) - плохой стиль.
Код:

SeedRnd(MilliSecs())



While Not (KeyHit (1))

If ChannelPlaying (channel) = 0 SelectRandMusic("music")

Wend

End


Function SelectRandMusic(DIR$)
Local counter%=0
local channel%=0
Local dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
counter=counter+1
EndIf
If file$="" Exit
Wend
CloseDir dir_h
Print "files="+counter
Local iR%=Rand(1,counter%)
If Not counter Return False
counter=0
dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
counter=counter+1
If counter%=iR
 Print "select - "+IR+" = "+file$
 channel=PlayMusic(DIR$+"\"+file$)
Exit
EndIf
EndIf
Wend
Return channel
End Function

2 Dizels:
не понял - как это: музыка играет,а игра не грузится?
надо полагать - так:
вычлени цикл из пример Жеки в функцию а-ля:
Код:

Function UpdateMusic(channel)
 If ChannelPlaying (channel) = 0 channel=SelectRandMusic("music")
 return channel
End Function

и просто где-нибудь в главном цикле твоей программы (не мудурствуя лукаво - перед RenderWorld) напиши вызов приведённой выше ф-ции
Код:

;.....
channel=UpdateMusic(channel)
;....
RenderWorld

И вот теперь уже позаботься об области видимости переменной channel -
либо объяви её перед главным циклом
либо уж пихай в глобал

impersonalis 28.09.2005 22:39

Кстати после описанных манипуляций - нигде вызво функции SelectRandMusic прописывать необязательно - во время выполнения игры программа на первом же кадре обнаружит отсутствие фоновой музыки и выполнит необходимые действия

Жека 29.09.2005 08:07

Ага, зря зарезал, на Return не обратил внимания...

Dizels 07.10.2005 01:09

Заранее прошу прощения за мою тупость, вот код, который я вставил, согласно вашим высказываниям:
Код:

SeedRnd(MilliSecs())

Function UpdateMusic(channel)
If ChannelPlaying (channel) = 0 channel=SelectRandMusic("music")
Return channel
End Function

Function SelectRandMusic(DIR$)
Local counter%=0
Local channel%=0
Local dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
counter=counter+1
EndIf
If file$="" Exit
Wend
CloseDir dir_h
Print "files="+counter
Local iR%=Rand(1,counter%)
If Not counter Return False
counter=0
dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
counter=counter+1
If counter%=iR
Print "select - "+IR+" = "+file$
channel=PlayMusic(DIR$+"\"+file$)
Exit
EndIf
EndIf
Wend
Return channel
End Function

channel=UpdateMusic(channel)

Объясните, не как не пойму :wallbash:

Dizels 07.10.2005 01:10

Остаеться начальная проблема:проигрываеться обин файл, а дальше тишина.

Dizels 07.10.2005 21:28

???Подскажите!Или если я надоел с этим вопросом, то так и скажите

alcosholik 07.10.2005 21:57

А ты эту строчку
channel=UpdateMusic(channel)
в основном цикле пишешь?

Dizels 07.10.2005 22:04

Ну вроде да, посмотри выше - самая последняя сторчка кода

alcosholik 07.10.2005 22:10

Я вижу, что последняя строчка. Покажи тогда код, в котором ты вызываешь функцию, а не одну строчку этого кода.

impersonalis 08.10.2005 01:03

Основной цикл здесь - цикл в котором выполняются ф-ции обновления и логики NPC а так же рендер и просчёт коллизий. Судя по результату - один файл играет - ты пишешь это не в главном цикле.

Dizels 08.10.2005 11:02

Я понимаю, что я что-то делаю не так, но вот что именно - ни как не доходит. Вот еще раз ВЕСЬ код который у меня написан для воспроизведения музыки:
Код:

Graphics3D 1024,768,32,1
................
SeedRnd(MilliSecs())

Function UpdateMusic(channel)
If ChannelPlaying (channel) = 0 channel=SelectRandMusic("music")
Return channel
End Function

Function SelectRandMusic(DIR$)
Local counter%=0
Local channel%=0
Local dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
counter=counter+1
EndIf
If file$="" Exit
Wend
CloseDir dir_h
Print "files="+counter
Local iR%=Rand(1,counter%)
If Not counter Return False
counter=0
dir_h%=ReadDir(DIR$)
While True
file$=NextFile$(dir_h)
If Upper$(Right(file$,3))="MP3"
counter=counter+1
If counter%=iR
Print "select - "+IR+" = "+file$
channel=PlayMusic(DIR$+"\"+file$)
Exit
EndIf
EndIf
Wend
Return channel
End Function

channel=UpdateMusic(channel)
.............................
Flip
Wend
End

Вот!А теперь по поводу высказывания alcoSHoLiK'a мне кажеться, что именно он подобрался к сути вопроса - как вызывать функцию?Потомучто как мне казалось - строка
Код:

channel=UpdateMusic(channel)
как раз таки ее и вызывает!Объясните или дополните кодом. :SOS: :unsure: :dontknow:

impersonalis 08.10.2005 13:30

Код:

while not keyhit(1)
......................
channel=UpdateMusic(channel)
.............................
Flip
Wend
End



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

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