AS3 Spritesheet动画

时间:2014-02-23 15:11:33

标签: actionscript-3 flash animation sprite-sheet

我正在开发一个游戏,那里会有不同方面的人,我想知道如何在每个动画帧中加载一个文件,经过大量搜索后我在另一个flash项目中创建了一个新的Ball类并制作了我自己这个代码只是为了测试

public class Ball extends MovieClip {

    private var spriteSheet:Bitmap;

    public function Ball() 
    {
        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
        loader.load(new URLRequest("Ball.png"));
    }

    private function onFrameLoop(e:Event)
    {
        switchFrame();
    }

    private function switchFrame()
    {
        var frameBitmapData:BitmapData = new BitmapData(50, 50);
        frameBitmapData.copyPixels(spriteSheet.bitmapData, new Rectangle(0, (50*(currentFrame-1)), 50, 50), new Point(0,0));
        var frame:Bitmap = new Bitmap(frameBitmapData);
        this.addChild(frame);
    }

    private function onLoadComplete(e:Event)
    {
        var loaderInfo:LoaderInfo = e.target as LoaderInfo;
        spriteSheet = loaderInfo.content as Bitmap;

        this.addEventListener(Event.ENTER_FRAME, onFrameLoop);
    }
}

}

它有效,我只在Ball MovieClip符号上添加了5个空白关键帧。问题是,如果我计划为移动设备制作这款游戏​​,并且同时可能有20个人在舞台上,这是否足够快?还必须有另一种方式,因为XML文件必须用于正确的事情吗?那是什么呢?

PD:我知道每次执行switchFrame函数时都不会删除帧Bitmap。

我需要一个好的答案,不要把我联系到我可能不理解的东西

1 个答案:

答案 0 :(得分:2)

你基本上每帧都在创建一个新的BitmapData对象 - 真的很糟糕。你不清理旧框架 - 双重真的很糟糕。不能强调。您需要一个Bitmap对象和一个BitmapData对象(以及一个Rectangle对象)才能生成一个工作精灵。想象一下,你会得到1000个球,每个球每帧制作一个位图 - 你的游戏会很快崩溃。但是,如果每个球都有一个局部位图,那么一切都应该运行得足够顺畅。

我在制作精灵表时遇到了另一个警告,如果屏幕上的对象不多,则copyPixels()方法有效,如果你越过某个阈值,你最好制作一个BitmapData。 1}}动画的每一帧的对象,只需更改您的精灵每帧的那些位图的bitmapData个链接。

public class Ball extends MovieClip {

private static var spriteSheet:BitmapData; // first, why storing a Bitmap if you don't need it be moving?
private static var spriteArray:Vector.<BitmapData>; // This will store split spritesheet

private var bitmap:Bitmap; // this will be displaying proper frame
private var currentFrame:int; // what frame are you displaying
public static function initialize():void {
    // loading static assets should better be made in a static function
    if (!spriteSheet) {
       var loader:Loader = new Loader();
       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
       loader.load(new URLRequest("Ball.png"));
    }
}
public function Ball() {
    bitmap=new Bitmap(); // null bitmap is displayed
    addChild(bitmap);
    currentFrame=0;
    addEventListener(Event.ENTER_FRAME, onFrameLoop,null,0,true); // weak listener
    // to not hog memory if you'd create and remove balls
}
private function onFrameLoop(e:Event)
{
    switchFrame();
}

private function switchFrame()
{
    if (!spriteArray) return; // oops, not initialized
    currentFrame++;
    if (currentFrame>=spriteArray.length) currentFrame=0;
    bitmap.bitmapData=spriteArray[currentFrame]; // voila. Now this particular Ball
    // will display the proper BitmapData out of sliced sprite sheet.
}

private static function onLoadComplete(e:Event)
{
    var loaderInfo:LoaderInfo = e.target as LoaderInfo;
    spriteSheet = (loaderInfo.content as Bitmap).bitmapData; // store the bitmapdata
    // now cut the loaded sprite sheet apart
    var i:int=Math.floor(spritesheet.width/50); // how many frames are in there
    var r:Rectangle=new Rectangle(0,0,50,50);
    var p:Point=new Point(); // why making N identical points? Just make one
    spriteArray=new Vector.<BitmapData>();
    for (var j:int=0;j<i;j++) {
        var bd:BitmapData=new BitmapData(50,50);
        r.x=50*j; // update rectangle to cut next frame
        bd.copyPixels(spriteSheet,r,p); // cut the frame in a new BitmapData
        spriteArray.push(bd); // store the frame
    }
    // once this is complete, your sprite sheet is ready
}
}

}