Hi there,
I wrote the code below to convert timeline-animated movieclips into bitmaps to improve performance.
The only problem is, I have created a loop to draw each frame of the movieclip over 300 times.
The bug I am experiencing is that when the function BitmapMC is run 314 times, I get the error: “ArgumentError: Error #2015: Invalid BitmapData.”
It seems as if Flash is running out of memory or something, but I can’t figure out what might be causing this problem.
Is there an alternative to draw() that I could use? I’d like to use copypixels, but of course I have to draw the bitmap first before I can do that.
Incidentally, the animation I have converting to bitmap has 30 frames, so in total it is drawing about 9,340 bitmap images before it crashes.
Each bitmap image is 78 x 125.5 pixels.
The code is below:
package com.jpardoe.utils
{
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.utils.Dictionary;
import flash.display.FrameLabel;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class BitmapMC extends MovieClip
{
private var frameLabel:FrameLabel;
private var frameNames:Dictionary = new Dictionary();
private var frames:Dictionary = new Dictionary();
private var bitmaps:Dictionary = new Dictionary();
private var bd:BitmapData;
private var bmp:Bitmap;
private var mcWidth:Number;
private var mcHeight:Number;
private var i:int;
private var j:int;
private var currFrame:int;
private var startFrame:int;
private var lastFrame:int;
private var rect:Rectangle;
private var point:Point;
public function BitmapMC(mc:MovieClip, scale:Number = 1):void
{
mcWidth = mc.width;
mcHeight = mc.height;
mc.gotoAndStop(1);
// Cycle through frames to find maximum width and height
// Set bitmap width/height variables accordingly
for(i = 1; i<mc.totalFrames; i++){
mc.gotoAndStop(i);
if(mc.width > mcWidth){
mcWidth = mc.width;
}
if(mc.height > mcHeight){
mcHeight = mc.height;
}
}
// Cycle through frames to detect all frame labels
for(i = 0; i<mc.scenes[0].labels.length; i++) {
frameNames[mc.scenes[0].labels*.frame] = mc.scenes[0].labels*.name;
}
for(i = 1; i<=mc.totalFrames; i++){
mc.gotoAndStop(i);
bd = new BitmapData(mcWidth, mcHeight, true, 0x00000000);
//bd.fillRect(bd.rect, 0x00000000);
bd.draw(mc);
bmp = new Bitmap();
bitmaps* = bd;
frames* = bmp;
}
this.addChild(bmp);
}
public function Play(frameName:String, freq:int = 30):void
{
// Cycle through frameNames dictionary to find the start frame number, specified by frameName (e.g. finds frame number of frame named 'walk')
for (var val:* in frameNames) {
if(frameNames[val] == frameName){
currFrame = val;
startFrame = val;
}
}
var frameTimer:Timer = new Timer(1000/freq);
frameTimer.addEventListener(TimerEvent.TIMER, nextFrameFunc);
frameTimer.start();
function nextFrameFunc(evt:TimerEvent):void
{
bmp.bitmapData = bitmaps[currFrame];
lastFrame = currFrame;
if(frameNames[currFrame] == 'repeat'){
currFrame = startFrame;
}
if(frames[currFrame+1]){
currFrame++;
} else {
frameTimer.stop();
}
}
}
}
}
Any ideas would me much appreciated!