BitmapData имеет метод scroll()
, который вы можете использовать - http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#scroll()
По сути, в каждом кадре вы рисуете только один столбец данных пиксельной ценности (ваши BitmapData будут отображать ваш звук, а каждый столбец пикселей - ценность данных захвата) - по большей части вы, вероятно, только будет использовать setPixel()
для установки значения громкости.
Продолжайте двигаться вдоль одного столбца пикселей для одного кадра данных, затем, когда вы достигнете своего порога (в самой правой части BitmapData), используйте scroll()
, чтобы переместить данные на один пиксель влево (вы потеряет крайний левый столбец пикселей), затем продолжу рисовать в последнем столбце (справа) пикселей. Вы создадите постоянно обновляемый дисплей громкости.
Наконец, используйте lock()
и unlock()
до и после рисования, чтобы остановить Flash от обновления экрана в это время.
Я бы посоветовал иметь какое-то ограничение - предметы, которые растут бесконечно = большие проблемы позже
Редактировать
Вот код. Это занимает 0 мс (используя getTimer()
в отладочном плеере) для рендеринга. В конечном итоге вы столкнетесь с проблемами, поскольку объем тома неограниченно растет, что никогда не бывает хорошо. Если вам нужно только удерживать последнее количество кадров x, этот код еще проще.
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
public class Main extends Sprite
{
private var m_bmd:BitmapData = null;
private var m_vol:Vector.<int> = null;
private var m_currVol:int = 0;
public function Main():void
{
// create our bmd
this.m_bmd = new BitmapData( 400.0, 200.0, false, 0 );
// add it to the stage
var b:Bitmap = new Bitmap( this.m_bmd );
this.addChild( b );
// create our volume array
this.m_vol = new Vector.<int>();
// set our current volume
this.m_currVol = this.m_bmd.height / 2;
// start our volume listener
this.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
}
private function _onEnterFrame( e:Event ):void
{
var start:int = getTimer();
// update our volume and add it to our array
this.m_currVol += int( ( Math.random() * 10.0 ) - 5.0 ); // adds a random int between -5 and 5
this.m_currVol = ( this.m_currVol < 0 ) ? 0 : ( this.m_currVol > this.m_bmd.height ) ? this.m_bmd.height : this.m_currVol; // clamp it to the bitmap data height
this.m_vol[this.m_vol.length] = this.m_currVol;
// lock our bitmap
this.m_bmd.lock();
// clear the bitmap
this.m_bmd.fillRect( this.m_bmd.rect, 0 );
// go through and draw our volumes (for max the size of the bmd)
var len:int = ( this.m_vol.length < this.m_bmd.width ) ? this.m_vol.length : this.m_bmd.width;
var startX:int = ( this.m_vol.length < this.m_bmd.width ) ? 0 : this.m_vol.length - this.m_bmd.width;
for ( var i:int = 0; i < len; i++ )
this.m_bmd.setPixel( i, this.m_vol[startX + i], 0xffff00 );
// unlock our bitmap
this.m_bmd.unlock();
trace( "This took " + ( getTimer() - start ) + "ms to render" );
}
}
}
Добавьте в полосу прокрутки, чтобы изменить переменную startX
(по умолчанию она всегда будет отображать последний объем данных), и вы там