Simple Starling Tutorial: Initialization and First Sprite

admin  

In this simple Starling tutorial we’re gonna load a simple texture and display it on the screen. Starling is a trendy as3 framework wrote by the same person who wrote parrow for iOS. It uses GPU but is created for 2d games with the idea in mind that speed matters when we are talking about games. That makes it a good candidate if you are looking for a framework to develop in as3 games for mobiles.

To use starling you have to download the swc and put it in your lib folder. You have to compile the project to flash 11.1 so you might have to update the flex compiler to a  later version.

First of all we have to mention that GPU, speed and Starling are not good friends with vector graphics. In starling we have a similar structure of classes similar to the ones in flash. Instead of  flash.display.Sprite we have to use starling.display.Sprite which exposes similar methods with the original. The main difference comes in implementation. In traditional flash programs for each sprite the specific object exists in the computer memory. At run time the CPU renders all the objects and the image is displayed. This is not always the fastest way to do things and that’s why specialized hardware to perform graphical rendering appeared. Starling (being a wrapper over stage3d which uses OpenGL/DirectX depending on platform) uses GPU to render the scenes. That means that at some point in time (usually in the beginning of the game) a set of images called textures are loaded in the by the GPU. Then starling running in the CPU gives asynchronous commands to the GPU about how to render the scenes. The CPU continues to run without waiting for the things to be rendered. That should be blazing fast for to reasons: specialized hardware is performing the rendering part and a certain amount of parallelism is achieved: both CPU and GPU runs in parallel.

In our example we try to touch 2 issues:

  • Initialization of starling
  • Uses of Textures and texture atlas

Simply put a texture is an image loaded in graphic memory. We can use that image to display it 1 time or 10000 times on screen(GPU will do that for us). We can also tell the GPU to crom and display only parts of it. One limitation of textures is that that each dimension has to be a “round” number like 64, 128, 1024 or any other power of 2. That’s why in order to save some amount of memory we can put many objects in one big texture and to define a crop region for each small texture. That is called Texture atlas and we can define it as in the following example or via xml files.

Considering the above mentioned things let’s see our first self explanatory example, which consists of 2 classes displaying one moving image on screen. The image is loaded as a Texture(starling is loading it directly in the GPU memeory), then a region defined in a TextureAtlas is used from the Texture.

 

package
{
    
    import net.hires.debug.Stats;
    
    import starling.core.Starling;
    import flash.display.Sprite;
    
    [SWF(frameRate="60", width="800", height="600", backgroundColor="0x333333")]
    public class MyStarling extends Sprite
    {
        
        private var stats:Stats;
        private var myStarling:Starling;
        
        public function MyStarling()
        {
            stats = new Stats();
            this.addChild(stats);
            
            myStarling = new Starling(MyStarlingSprite, stage);
            myStarling.antiAliasing = 1;
            myStarling.start();
        }		
                    
        
    
    }
}

package
{
    import starling.display.Image;
    import starling.display.Sprite;
    import starling.events.Event;
    import starling.textures.Texture;
    import starling.textures.TextureAtlas;

    import flash.display.Bitmap;
    import flash.geom.Rectangle;

    
    public class MyStarlingSprite extends Sprite
    {
        [Embed(source="../media/images/sprites.png")]
        private static var Sprites:Class;
        
        private static var atlas:TextureAtlas;
        
        private var bg:Image;
        
        public function MyStarlingSprite()
        {
            super();
            
            atlas = getAtlas();
            
            this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            this.addEventListener(Event.ENTER_FRAME, enterFrame);
        }

        public static function getAtlas():TextureAtlas
        {
            var bitmap:Bitmap = new Sprites();
            var texture:Texture = Texture.fromBitmap(bitmap);
            var atlas:TextureAtlas = new TextureAtlas(texture);
            
            atlas.addRegion("MY_SPACESHIP", new Rectangle(10,10,70,20));
            
            return atlas;
        }
        
        
        private function onAddedToStage(event:Event):void
        {
            bg = new Image(atlas.getTexture("MY_SPACESHIP"));
            this.addChild(bg);
        }
        
        private function enterFrame(event:Event):void
        {
            bg.x += 1;
            
            if (x > 400) x = 0;
        }		

    }
}

If you want to keep the loaded assets in a separate class you can simply do it like that:

package
{
    import starling.textures.Texture;
    import starling.textures.TextureAtlas;
    
    import flash.display.Bitmap;
    import flash.geom.Rectangle;
    
    public class Assets
    {
        [Embed(source="../../media/images/sprites.png")]
        private static var Sprites:Class;
            
        public static var atlas:TextureAtlas = getAtlas();
            
        public static function getAtlas():TextureAtlas
        {
            var bitmap:Bitmap = new Sprites();
            var texture:Texture = Texture.fromBitmap(bitmap);
            var atlas:TextureAtlas = new TextureAtlas(texture);
                
            atlas.addRegion("MY_SPACESHIP", new Rectangle(10,10,70,20));
            return atlas;
        }
    }
}