Domanda

Im working on a game where there will be people with different aspects and i was wondering how could i load a single file with every frame of the animation, after searching a lot i created a new Ball class in another flash project and made myself this code just to test

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);
    }
}

}

And it worked, i just added 5 blank key frames on the Ball MovieClip Symbol. The problem is, is this fast enough if im planning to make this game for mobile devices and there will be maybe 20 people on the stage at the same time? Also there must be another way because the XML file must be used for something right? SO what is that other way?

PD: I know im not removing the frame Bitmap each time the switchFrame function is executed.

Please I need a good answer, don't link me to stuff i probably won't understand

È stato utile?

Soluzione

You are basically creating a new BitmapData object each frame - REALLY BAD. You don't clean up older frames - DOUBLE REALLY BAD. Can't emphasize enough. You need one Bitmap object, and one BitmapData object (and one Rectangle object too) to make a working sprite. Imagine you'd get 1000 balls, each making a bitmap per frame - your game will crash too soon. But, if each of them balls will have a local bitmap, everything should run smoothly enough.

There is another caveat I've hit when making me sprite sheets, copyPixels() approach works if there aren't many objects on the screen, if you cross a certain threshold, you'd better make one BitmapData object for each frame of your animation, and just change bitmapData links of those bitmaps your sprites have each frame.

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
}
}

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top