Search code examples
actionscript-3starling-framework

How to animate a spritesheet without an atlas?


I have a sprite sheet for about 30 frames of different animations that are not in order.

I would like to use Starling to make the animations but I do not have / don't have the time to make a atlas xml. Even if I did, I would rather NOT use the atlas.

Furthermore, the sprite sheet has a black background and most examples I researched have transparent background.

Any help would be appreciated. Thanks.


Solution

  • Here is an example on how to retrieve the textures from the atlas giving the frames you want and the frames width and height:

    package
    {
        import starling.textures.Texture;
        import flash.geom.Rectangle;
    
        public class AnimFromAtlas
        {
            public function AnimFromAtlas( )
            {
    
            }
    
            public static function TexturesFromAtlas( atlas:Texture, frames:Array, frameWidth:int, frameHeight:int ):Vector.<Texture>
            {
                // declare x and y properties 
                var x:int, y:int = 0;
                // create the base rectangle with the flrame width and frame height, we just have to update the x and y values.
                var region:Rectangle = new Rectangle( 0, 0, frameWidth, frameHeight );
                // create the texture vector that we have to return
                var textures:Vector.<Texture> = new <Texture>[];
                // calculate the max frame on one line on the atlas
                var framesOnLine:int = atlas.width / frameWidth;
    
                // loop the frames to get the textures on the atlas
                for( var i:int = 0; i<frames.length; ++i )
                {
                    x = (int( (frames[i] % framesOnLine) ) * frameWidth);   
                    y = (int( (frames[i] / framesOnLine) ) * frameHeight);
                    region.x = x;
                    region.y = y;
                    textures[i] = Texture.fromTexture(atlas, region);
    
                    trace( region );
                }
    
                // fix the vector for better performances
                textures.fixed = true;
    
                // return the textures
                return textures;
            }
        }
    }
    

    So you just have to call the static method AnimFromAtlas.TexturesFromAtlas(yourSpriteSheet, [1,2,5,8,3], 150, 100);

    If you have your atlas as Bitmap and not as Texture you can use Texture.fromBitmap(yourBitmap) to get the Texture.

    I didn't tried it so maybe it don't work as you want but i think it should do the trick, i added a trace of the rectangles found for the textures so you can see if it seems credible or not.

    for the black background, you can do it directly with as3 like this:

    var bitmapData:BitmapData = yourAtlasBitmap.bitmapData;
    var black     :uint = 0xff000000;  // the black color to replace
    var trans     :uint = 0x00000000;  // the transparent color that will replace the black
    var mask      :uint = 0xffffffff;  // the mask to use (i always use white here)
    // the target rectangle
    var rect      :Rectangle = new Rectangle( 0, 0, bitmapData.width, bitmapData.height );
    
    // do the replacement of the color
    bitmapData.threshold( bitmapData, rect, new Point(0,0), "==", black, trans, mask, true );
    
    // create a new Bitmap with the new BitmapData
    var yourNewBitmap:Bitmap = new Bitmap(bitmapData);
    

    I hope this could help you.