Музыка во флеш играх

Февраль 9th, 2010 автор: Oleg Antipov

О да, это то самое, что отжирает в особо запущенных случаях 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

Категория: Хитрости

Оставить комментарий