Blog posts


  • Keeping aspect ratio in responsive CSS

    June 19, 2013 | Tags: CSS, HTML, Snippet
    Having problem with retaining the aspect ratio when doing responsive design? Setting width in percentage is easy, but doing the same for height will be ignored. The solution is to instead use padding in order to set the correct aspect ratio. In order for this to work the height must be set to 0.

    The example below shows an element that will keep a 4:3 aspect ratio when scaled. The percentage set as padding-bottom will be the ratio, so for 4:3 we'll use 75%. If you instead want a complete square you should use 100%.

    <style>

    .my-box {
    background:#cccccc;
    width:100%;
    height:0;
    padding-bottom:75% /* relative to the element´s width */
    }

    </style>

    <div class="my-box">
    This box should be 4:3
    </div>

    Original solution found at: Pixel Acres


  • How to use Spine with Starling/AS3

    May 10, 2013 | Tags: Game development, Tools, Starling, AS3, Flash

    Hats off to the guys over at Esoteric Software. Not only did they live up to the Kickstarter promise to deliver generic AS3 runtime for their excellent 2d animation tool Spine, they also added a Starling version as a bonus! This post shows how to get going using Spine animation in your AS3/Starling project.

    Updated 2015-03-22 Since this post was originally written the Spine runtime has undergone a bit of refactoring. To reflect the changes the post was updated using the latest runtime for Spine as well as the latest Starling library (1.6 at time of writing).
     
    Spine is currently the most promising solution for 2d skeleton animation, featuring a lot of powerful features such as individual keyframing, skinning and more. The major advantages over traditional sprite sheets are that using skeletal animation uses far less memory and provides smoother animations and the ability to seamlessly shift from one animation to the next - something that makes your animations more vivid. Spine is currently offered for $60 and is definitely worth every cent of it. If you want to give it a try there's a export-disabled trial version for download. There are a couple of alternatives to Spine, but nothing comes close to its functionality. It's currently the most powerful 2d skeletal animation tool.

    Currently Spine does not have a texture packer built-in, so we will be using TexturePacker developed by Andreas Löw. It's a great tool that recently got even better with a content protection feature. If you haven't already you should definitely check it out!

    Setup the project

    Setup a new AS3 project inside FlashDevelop (or the IDE of your choice) and check under project properties so that it compiles for the latest Flash player version. (Or you can download the project here.)

    Download the latest version of Starling and place starling.swc in the lib-folder of your project. Right click on the file and select Add To Library.
     
     
    Download the latest Spine runtimes and copy the content of both spine-as3/src and spine-starling/src into your src folder:
     
     
     
    We've now created our project. Lets get some data into it and then return to do some coding.
     
     

    Export data from Spine

    Lets start by preparing the data. Once you've created your animations you need to get them out of Spine and into your project. This is done using the Export function.


    Be sure to use JSON as the data format and set the output path to src in your AS3 project:

     
     
     

    Create the sprite sheet using  TexturePacker

    Okay, so now we got the animation data, but we'll also need the body part graphics as a texture atlas. This is where TexturePacker comes in to do the job.

    Start TexturePacker, select all the images from your Spine project (we're using the Spineboy sample project for this demo)..


    .. drag and drop them into the Sprites panel of TexturePacker (you could also use the "Add Sprites" option inside of TexturePacker):


    In the TextureSettings panel, select "Sparrow / Starling" as Data Format and place both the Data file and Texture file in the src-path of your AS3 project:



    Lets write some code!

    Lets start by adding Starling into our Main class:
    package {
    import flash.display.Sprite;
    import flash.events.Event;
    import starling.core.Starling;

    public class Main extends Sprite {
    private var _starling:Starling;

    public function Main():void {
    if (stage)
    init();
    else
    addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void {
    removeEventListener(Event.ADDED_TO_STAGE, init);

    _starling = new Starling(MyStarlingApp, stage);
    _starling.start();
    }
    }
    }
    Next step is to add the MyStarlingApp class that we used as a constructor argument for Starling. Create a new class named MyStarlingApp and make it inherit from starling.display.Sprite.

    Embed the data files using [Embed(source="..",mimeType="application/octet-stream")] inside the class.

    Here's the complete code, I'll return to some of the more specific parts:
    package {
    import flash.utils.setTimeout;
        import spine.animation.AnimationStateData;
        import spine.starling.SkeletonAnimation;
        import spine.starling.StarlingAtlasAttachmentLoader;
        import spine.SkeletonData;
        import spine.SkeletonJson;
        import starling.core.Starling;
        import starling.display.Sprite;
        import starling.textures.Texture;
        import starling.textures.TextureAtlas;

    public class MyStarlingApp extends Sprite {
    [Embed(source="spineboy.xml",mimeType="application/octet-stream")]
    static public const SpineBoyAtlasXml:Class;

    [Embed(source="spineboy.png")]
    static public const SpineBoyAtlasTexture:Class;

    [Embed(source="spineboy.json",mimeType="application/octet-stream")]
    static public const SpineBoyJson:Class;

            private var _skeleton:SkeletonAnimation;

    public function MyStarlingApp() {
    var texture:Texture = Texture.fromBitmap(new SpineBoyAtlasTexture());

    var xml:XML = XML(new SpineBoyAtlasXml());

    var atlas:TextureAtlas = new TextureAtlas(texture, xml);
                var attachmentLoader:StarlingAtlasAttachmentLoader = new StarlingAtlasAttachmentLoader(atlas);
                var json:SkeletonJson  = new SkeletonJson(attachmentLoader);

    var skeletonData:SkeletonData = json.readSkeletonData(new SpineBoyJson());

    var stateData:AnimationStateData = new AnimationStateData(skeletonData);

    // Setup how to morph between different animation sets
    stateData.setMixByName("walk", "jump", 0.3);
    stateData.setMixByName("jump", "walk", 0.4);
    stateData.setMixByName("jump", "jump", 0.2);

    _skeleton = new SkeletonAnimation(skeletonData, false, stateData);
    _skeleton.x = 400;
    _skeleton.y = 460;
    _skeleton.state.setAnimationByName(0, "walk", true);

    setTimeout(makeJump, 3000);

    addChild(_skeleton);
    Starling.juggler.add(_skeleton);
    }

    private function makeJump():void {
    _skeleton.state.setAnimationByName(0, "jump", false);
    _skeleton.state.addAnimationByName(0, "walk", true, 2); // delay next animation by 2 seconds
    }
    }
    }
    All animations are referred to by the name given in Spine. For the Spineboy demo project there's two animations: "walk" and "jump".

    One of the powerful features of Spine is the smooth transitions between animations. This is made by defining "mixes" on the AnimationStateData object using the setMixByName function. The first parameter is the name of the animation that the transition will be made from, the second the animation that will be switched to and the third parameter is the transition time. In the code above the transition between "walk" and "jump" is set to 0.3 seconds. If no mixes have been defined the change in animation will occur instantly. To make the animations smoother you should set up mixes for all animation changes that can occur.

    To start an animation call the setAnimationByName function of the SkeletonAnimation object's state property. The first parameter is track, the second is the name of the animation and the third is if the animation should be looped.

    If you wish to play one animation and immediately after another, use addAnimationByName after setAnimationByName in order to stack animations that will be played after each other.

    Download source codeThe FlashDevelop project except the Spineboy data, which you can get from the Spine runtime download.

     

    Runtime sourceThe runtimes are undergoing continues updates, so the one used in the archive above may differ from the one available at http://esotericsoftware.com/spine-runtimes/.

  • $(window).height() vs $(document).height()

    April 23, 2013 | Tags: Javascript, Troubleshooting, jQuery
    I was trying to use the $(window).height() method in jQuery to get the height of the browser window but was instead getting the document height in return (same as $(document).height()).

    So, what to do if window height returns document height instead?

    Solution

    The problem is most likely that your HTML document lacks a <!DOCTYPE>-definition. So the solution to the problem is to add a valid <!DOCTYPE> like <!DOCTYPE HTML> in the top of the HTML file. When done $(window).height() should start to report the proper window height and not the document's.



  • Preserve textformat when changing text in Flash / AS3

    April 09, 2013 | Tags: Actionscript, AS3, Troubleshooting, Flash, Snippet
    Notice that the textformat that was defined for your TextField mysteriously disappears when you just change the text? A bit annoying, but the reason is that the format is not applied to the TextField itself but the text in it. Replace the text and you replace the textformat as well.

    This can however be solved by storing away the textformat before you change the text and then re-apply it like this:

    // Save the old textformat before changing the text
    var textFormat:TextFormat = buttonText.getTextFormat();

    // Change the text
    buttonText.text = "New text goes here";

    // Re-apply the textformat
    buttonText.setTextFormat(textFormat);


  • Correct font names in TextFormat.font (AS3)

    April 03, 2013 | Tags: Actionscript, AS3, Troubleshooting, Flash
    If you want to use TextFormat in order to set which font family and style you wish to use on a component in your Flash project you just might be a bit puzzled on how to express both family and style in just one field - TextFormat.font.

    The problem

    If you plan to use the regular version of the font family ("Veto Com" in the sample, but could be "Arial", "Verdana" or the font of your choice), you'll just go with:
    import flash.text.TextFormat;

    var textFormat:TextFormat = new TextFormat();
    textFormat.font = "Veto Com";
    But if you want to use the Light style instead of Regular it's a bit trickier, because you need to know the font name including both family and style. Unfortunately there are no standards so it might differ between font sets.

    The solution

    There are two ways to get the correct font name:

    1. In Windows, locate the font file and open it to display the font information window. It will look something like this and the correct font name to use will be displayed in upper left corner:


    2. Add a textfield to your project and give it an instance name. Set both the Family and Style properties to the font you want. Then in code access the font property of the textfield and trace it using trace(myTextField.getTextFormat().font);
    Source for this solution: http://blog.erikphansen.com/actionscript-textformatfont-values/

    Enter the font name that you get from either of the methods above in your code:
    import flash.text.TextFormat;

    var textFormat:TextFormat = new TextFormat();
    textFormat.font = "Veto Com Light";