Онлайн-справочник по самым часто задаваемым вопросам из темы "Как сделать?" на форуме QSP.su

6.7. Как сделать плейлист?

Прежде, чем приступить к прочтению данной статьи, ознакомьтесь со статьёй "Как зациклить мелодию?".

Если вы поняли, как зациклить одну мелодию, а то и как зациклить мелодию для проигрывания на отдельной локации, то смело переходите к следующим примерам и решениям.

Плейлист, как правило, представляет из себя список проигрываемых файлов в том порядке, в котором эти файлы должны проигрываться.

Мы рассмотрим случай, когда четыре файла должны проигрываться друг за другом в непрерывном порядке. И тут у нас есть несколько вариантов решения поставленной задачи.

Вариант первый. Файлы поименованы поочерёдно

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

`music_1.mp3`

`music_2.mp3`

`music_3.mp3`

`music_4.mp3`

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

На самой первой локации в игре обозначаем номер первой проигрываемой композиции, общее число файлов, и в системную переменную `$counter` прописываем название локации-счётчика.

! # start
if filescount=0:
    
! если ни в одной из переменных не записано значение
    filescount=4    ! общее число проигрываемых файлов 4
    current_file=1    ! номер файла, с которого хотим начать, 1. т.е. это будет файл с именем music_1.mp3
    play 'music_<<current_file>>.mp3'    ! запускаем проигрывание файла с указанным номером
    $counter='Counter'    ! локация-счётчик так и будет называться Counter
end

Теперь на локации-счётчике пишем такой код:

! # Counter
if no isplay('music_<<current_file>>.mp3'):
    
! если текущий файл больше не проигрывается
    current_file+=1    ! увеличиваем номер на единицу
    if current_file>filescount:
        
! если получившийся номер больше количества файлов
        current_file=1    ! возвращаем номер самого первого файла
    end
    play 'music_<<current_file>>.mp3'    ! запускаем проигрывание файла с указанным номером
end

Вот и всё. Наш непрерывный плейлист готов.

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

Например, наши файлы называются так:

`комната_1.mp3`

`комната_2.mp3`

`комната_3.mp3`

`коридор_1.mp3`

`коридор_2.mp3`

`коридор_3.mp3`

`коридор_4.mp3`

Тогда код может выглядеть так:

! # Counter
if $curloc='комната' and $loc_theme<>'комната':
    
! если мы оказались на локации комната, но выставлена не тема комнаты
    close '<<$loc_theme>>_<<current_file>>.mp3'    ! закрываем то, что сейчас проигрывается
    $loc_theme='комната'    ! вносим в переменную $loc_theme слово комната
    current_file=1    ! выставляем номер файла, с которого нужно стартовать
    filescount=3    ! для комнаты в плелисте будет только три файла, поэтом указываем число файлов 3
end
if $curloc='коридор' and $loc_theme<>'коридор':
    close '<<$loc_theme>>_<<current_file>>.mp3'
    $loc_theme='коридор'
    current_file=1
    filescount=4
end
if no isplay('<<$loc_theme>>_<<current_file>>.mp3'):
    
! если текущий файл больше не проигрывается
    current_file+=1    ! увеличиваем номер на единицу
    if current_file>filescount:
        
! если получившийся номер больше количества файлов
        current_file=1    ! возвращаем номер самого первого файла
    end
    play '<<$loc_theme>>_<<current_file>>.mp3'    ! запускаем проигрывание файла с указанным номером
end

У такого подхода есть один недостаток. Мы не можем использовать произвольные имена файлов для организации плейлиста, а ведь нам может потребоваться такой вариант, если файлы разбросаны по нескольким папкам. В этом случае нам потребуется следующий вариант.

Вариант второй. Плейлист с произвольными именами файлов

Данный способ предусматривает использование лишь одной переменной, однако для его реализации потребуется написать гораздо больше кода. Например, у нас есть такие файлы:

`amb/zoo.mp3`

`amb/monkey.mp3`

`zoo/buss.mp3`

`texlab/drillmusic.mp3`

На локации-счётчике мы будем проверять, проигрывается ли мелодия, записанная в переменную `$music`, и если мелодия уже не проигрывается, то запускать следующую.

Поскольку на начало игры у нас не проигрывается ни одна мелодия, в первый раз нам нужно проверять не проигрывается ли последняя из списка, и тогда автоматически у нас запустится первая То есть на самой первой в игре локации мы записываем в переменную `$music` самую последнюю мелодию из списка, а так же в переменную `$counter` помещаем название локации-счётчика.

! # start
$music='texlab/drillmusic.mp3'    ! добавили в переменную music самую последнюю проигрываемую мелодию
$counter='Counter'    ! в системную переменную прописали название локации-счётчика Counter

Осталось на локации-счётчике прописать код нашего плейлиста.

! # Counter
if no isplay($music):
    
! если мелодия, записанная в music не проигрывается
    
! с помощью сложного условия переключаем мелодию на следующую
    if $music='amb/zoo.mp':
        $music='amb/monkey.mp3'
    elseif $music='amb/monkey.mp3':
        $music='zoo/buss.mp3'
    elseif $music='zoo/buss.mp3':
        $music='texlab/drillmusic.mp3'
    elseif $music='texlab/drillmusic.mp3':
        $music='amb/zoo.mp3'
    end
    play $music
end

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

Разбирать вариант с разными плейлистами для разных локаций не будем. Код получится достаточно громоздким, и нам потребуется ещё одна переменная, чтобы отличать, какой плейлист сейчас проигрывается. Тем не менее такой вариант, если он вам удобен, вполне имеет право на существование.

Третий вариант. Плейлист в массиве

Этот вариант по сути объединяет два предыдущих варианта. Здесь мы можем использовать произвольные имена файлов, как во втором варианте, но производить переключение на следующий трек, просто зная номер проигрываемого трека.

Единственным недостатком этого варианта можно посчитать то, что пути ко все проигрываемым файлам заносятся в массив и остаются в нём на протяжении всей игры, что нагружает память. Однако, этот недостаток сложно счесть недостатком, ведь чтобы забить даже 100 мегабайт оперативной памяти таким образом вам понадобятся либо ооочень длинные пути, либо оооочень много этих самых путей.

Итак, на самой первой локации в игре мы формируем массив с именами файлов для нашего плейлиста, выставляем номер трека, с которого хотим запустить воспроизведение, и не забываем про локацию-счётчик, название которой нам нужно прописать в переменную `$counter`:

! # start
if arrsize('$playlist')=0:
    
! если массив с путями к проигрываемым файлам ещё не создан
    $playlist[0]='amb/zoo.mp3'
    $playlist[1]='amb/monkey.mp3'
    $playlist[2]='zoo/buss.mp3'
    $playlist[3]='texlab/drillmusic.mp3'
    
! ячейки массива нумеруются по порядку, это очень удобно
    current_file=0    ! в данную переменную вносим номер ячейки с названием того трека, который хотим запустить, и...
    
! ...запускаем трек:
    play $playlist[current_file]
    
! системной переменной $counter присваиваем название локации-счётчика
    $counter='Counter'
end

Нам осталось на локации-счётчике написать код, похожий на код из первого варианта:

! # Counter
if no isplay($playlist[current_file]):
    
! если мелодия больше не проигрывается
    current_file+=1 ! увеличиваем номер трека на единицу
    if current_file=arrsize('$playlist'):
        
! если полученый номер совпадает с размером массива
        current_file=0 ! пора снова воспроизводить трек с номером 0
    end
    play $playlist[current_file]    ! воспроизводим указанный трек
end

Заключение

Как видите, последний вариант практически лишён недостатков первых двух вариантов. Использование массива в данном случае сильно упрощает как написание, так и чтение кода. Если развить этот вариант и дальше, чтобы добиться работы разных плейлистов на разных локациях, то можно прийти к решению, которое предложил `Werewolf` в своём Гибком плейлисте. Если решили разрабатывать собственную систему управления музыкой в игре, ознакомьтесь с наработками `Werewolf`а. Вполне возможно, все ваши задумки уже реализованы в удобной и лаконичной системе.