Каждый кадр отрисовать в отдельную битмапдату, кинуть их все в массив. Дальше в одной bitmap менять битмапдату на значение из массива. Чем плох этот способ по сравнению с маской и скроллом?
Добавлено через 6 минут
Пример кода 5-ти летней давности, нарезает длинную .png c кадрами на битмадаты и затем проигрывает их.
Код AS3:
package engine.graphic
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Timer;
/**
* ...
* @author Bletraut
*/
public class AnimatedBitmap extends Bitmap
{
private var _currentFrame:uint = 0;
private var _totalFrames:uint = 0;
private var _frameSize:Rectangle = new Rectangle(0, 0, 0, 0);
private var _animationTimer:Timer;
private var _animationDelay:Number = 100;
private var ON_PLAY:Boolean = true;
private var ON_PAUSE:Boolean = false;
private var _framesCache:Vector.<BitmapData> = new Vector.<BitmapData>();
// Set & Get
public function get currentFrame():uint { return _currentFrame; }
public function get totalFrames():uint { return _totalFrames; }
public function get frameSize():Rectangle { return _frameSize; }
public function get animationDelay():Number { return _animationDelay; }
public function set animationDelay(n:Number):void
{
if (ON_PAUSE) return;
_animationDelay = n;
if (_animationTimer.hasEventListener(TimerEvent.TIMER)) _animationTimer.removeEventListener(TimerEvent.TIMER, onTick);
_animationTimer = new Timer(_animationDelay);
_animationTimer.addEventListener(TimerEvent.TIMER, onTick);
if (ON_PLAY) _animationTimer.start();
}
public function AnimatedBitmap(bitmapData:BitmapData, frame:Rectangle)
{
super(null, "auto", false);
_frameSize = frame;
createCache(bitmapData, _frameSize);
_animationTimer = new Timer(_animationDelay);
_animationTimer.addEventListener(TimerEvent.TIMER, onTick);
_animationTimer.start();
ON_PLAY = true;
}
public function play():void
{
if (ON_PAUSE) return;
ON_PLAY = true;
_animationTimer.start();
}
public function stop():void
{
if (ON_PAUSE) return;
ON_PLAY = false;
_animationTimer.stop();
}
public function pause():void
{
if (ON_PAUSE)
{
if (ON_PLAY) _animationTimer.start();
ON_PAUSE = false;
}
else
{
var f:Boolean = ON_PLAY;
this.stop();
ON_PLAY = f;
ON_PAUSE = true;
}
}
public function gotoAndPlay(frame:uint = 0):void
{
if (frame >= _totalFrames || ON_PAUSE) return;
_currentFrame = frame;
this.bitmapData = _framesCache[_currentFrame];
this.play();
}
public function gotoAndStop(frame:uint = 0):void
{
gotoAndPlay(frame);
this.stop();
}
private function onTick(e:TimerEvent):void
{
_currentFrame = (_currentFrame + 1 < _totalFrames) ? _currentFrame + 1 : 0;
this.bitmapData = _framesCache[_currentFrame];
}
private function createCache(src:BitmapData, frame:Rectangle):void
{
var w:int = Math.floor(src.width / frame.width);
var h:int = Math.floor(src.height / frame.height);
for (var i:int = 0; i < h; i++)
{
for (var j:int = 0; j < w; j++)
{
var b:BitmapData = new BitmapData(frame.width, frame.height, true, 0x000000);
b.copyPixels(src, new Rectangle(j * frame.width, i * frame.height, frame.width, frame.height), new Point(0, 0));
_framesCache.push(b);
}
}
_totalFrames = _framesCache.length;
}
}
}