Музыка во флеш играх
О да, это то самое, что отжирает в особо запущенных случаях 80% от общего размера flash игры. К сожалению миди и прочая треккерная музыка осталась в 20 веке, поэтому экономить приходится по другому.
Вообщем идея не нова и я уже обкатывал её на одной моей старой игрушке. Cуть идеи заключается в том, что многие электронные и не очень композиции состоят из повторяющихся лупов (музыкальных петель если по русски), поэтому можно хранить только эти самые лупы, и соответственно программно повторять их заданное количество раз. Как использовать безразрывные MP3 петли во флеше я рассказывал ранее здесь.
Для определения конца петли отвечает таймер который с определённым интервалом сравнивает текущую позицию в петле и её длину.
Кстати нашёл во флеше странный баг – длина музыкальной петли получаемая с помощью свойства length объекта Sound всегда получается больше чем фактический channel.position… С чем это связано я не знаю, буду рад если кто-нибудь прояснит ситуацию. Пока что в примере я тупо вбил реальную длину каждой петли.
Смотрите пример:
Его код:
var SndPos:int=0; var arrSnd:Array=new Array(); var channel:SoundChannel; var timerPL:Timer; //Загружаем наши музыкальные петли var A:mbonusA=new mbonusA(); var B:mbonusB=new mbonusB(); var C:mbonusC=new mbonusC(); var D:mbonusD=new mbonusD(); var E:mbonusE=new mbonusE(); //В связи с глюком, описанным в блоге выше, запоминаем реальную длинну каждой петли. A.realLength=1393; B.realLength=1393; C.realLength=6130; D.realLength=1393; E.realLength=1393; //Формируем последовательность воспроизведения петель arrSnd.push(A); arrSnd.push(B); arrSnd.push(A); arrSnd.push(A); arrSnd.push(C); arrSnd.push(C); arrSnd.push(D); arrSnd.push(D); arrSnd.push(E); arrSnd.push(E); arrSnd.push(B); arrSnd.push(B); arrSnd.push(C); arrSnd.push(C); arrSnd.push(D); arrSnd.push(E); arrSnd.push(D); arrSnd.push(D); arrSnd.push(D); arrSnd.push(E); arrSnd.push(D); arrSnd.push(D); //Создаём таймер. Он будет проверять не закончилась ли текущая петля. Если //закончилась - он будет переключать воспроизведение на другую петлю. timerPL= new Timer(1);//Можно сделать и побольше период опроса чтобы не грузить процессор timerPL.stop(); timerPL.addEventListener(TimerEvent.TIMER, timerPL_Timer); function timerPL_Timer(event:TimerEvent):void { //Раскоментируйте ниже строчку и убедитесь сами - position и length не совпадают! //trace("channel.position="+channel.position+" length="+(arrSnd[SndPos].length / //(arrSnd[SndPos].bytesLoaded / arrSnd[SndPos].bytesTotal))); //Если текущая петля отыграла - переключаем воспроизведение на другую петлю if(channel.position>=arrSnd[SndPos].realLength) { SndPos++; inf.text="Chunk №"+SndPos+"\n"+arrSnd[SndPos].toString(); channel=arrSnd[SndPos].play(0); if(SndPos+1==arrSnd.length) SndPos=0; } } //Кнопка запуска воспроизведения function buttPlay_Click(e : MouseEvent):void { if(channel) channel.stop(); channel=arrSnd[SndPos].play(0); timerPL.start(); } butt_play.addEventListener(MouseEvent.CLICK, buttPlay_Click); //Кнопка остановки музыки function buttStop_Click(e : MouseEvent):void { channel.stop(); timerPL.stop(); } butt_stop.addEventListener(MouseEvent.CLICK, buttStop_Click);
Метод можно расширить и накладывать несколько петель друг на друга, что даст более разнообразное звучание музыки. Также можно сделать динамическую смену музыки в зависимости от событий игры – например от спокойной музыки до агрессивной. Вообщем определённый потенциал эта идея имеет )
Весь код примера, с файлом FLA можно качнуть здесь: http://www.anegmetex.com/devblog/files/mustest.rar
