ActionScript 3.0

  • Supporting Multiple Screen Sizes with AS3

    I have been so busy lately, but I am still here, creating content for my ScaleViz blog, redrawing and re-sizing the artwork for ScaleViz, designing and planning out a new App, keeping up with my guitar practice, studying programming, spending quality time with the misses, oh and occasionally loosing it in between, I even had my first hypnotherapy client in a while, so had a quick swat on that and spent a good couple of days writing a specific script, anyway, I thought I’d take a break and post what I’m up to, I hope you find the information useful.

    Firstly it’s not just me that’s having to rework my app, it’s every app designer, obviously companies have a much greater advantage over lone developers, but were all having to deal with the same issues, currently there are a 4 screen sizes to support for, the original iPad/iPhone, which is 480×320, then the iPhone 4 and iPod Retina’s which are 960×640, then we have the iPad 1 and 2 which are 1024×768 and now the iPad 3 as well, which is 2048×1536, I also hear there’s going to be an Mini-iPad soon, then the iPhone 5, which I’m hoping, even though it’s reported to have a 5 inch screen, will still be 960×640 (oh well it’s not 960×640, more work, iPhone 5 res is 1136 x 640).

    To give non-programmers some idea of what were all up against, here’s the Shape Trainer button from my app ScaleViz, designed for the 480×320 screen.

    Now here’s the same button sized up for the iPad 3.

    Now if your app was originally designed for the iPad and your trying to make your app universal, then your in a much better position that those of us that designed for the original iPhone/iPod, because you will already have all of your 1024×768 images, and because of the way Apple designed the Retina screens 1024×768 apps still look OK at the 2048×1536 resolution, and sizing them down to get lower screen res images will not affect the quality.

    However, those of use that designed for the original screen size are having to size up all our graphics to support the various screen sizes, which in most cases means having to re-draw, scale up and re-export all of the graphics that your app uses, this could, and usually does mean, hundreds and hundreds of graphics.

    Anyway, while researching how to make universal apps, chapter 8 of the iOS Apps Cook Book I mentioned in this post, was very helpful and as usual Google is your friend when it comes to researching new stuff and I found the following link very useful as well.

    So from all the information I learned, I came up with this code;

    function checkRes():void {
    //trace(“Hello”);
    if (yRes >= 1024 && xRes >= 768) {
    //this is the screen res on my laptop which I use for testing
    //if (xRes == 1366 && yRes == 768) {
    trace(Capabilities.screenResolutionX);
    trace(Capabilities.screenResolutionY);
    box = new iPad;
    addChild(box);
    }
    else if (yRes == 960 && xRes == 640) {
    trace(Capabilities.screenResolutionX);
    trace(Capabilities.screenResolutionY);
    box = new iPhoneRetina;
    addChild(box);
    }
    else if (yRes == 480 && xRes == 320) {
    trace(Capabilities.screenResolutionX);
    trace(Capabilities.screenResolutionY);
    box = new iPhone;
    addChild(box);
    }

    What I am doing is setting the variable box, which is of type MovieClip, to load a different MovieClip, for each of the different resolutions, I have three MovieClips in my library all linked for ActionScript with linked AS3 names of iPad, iPhoneRetina and iPhone (inventive aren’t I), obviously each of the movie clips is set to the correct resolution for each device and each MovieClip contains an image which is also equal to the appropriate device resolution, I set my stage size at 1024×768 and set Flash to target iPhone/iPad, in other words universal, by the way I am using Flash CS5.

    This way, I can in theory anyway, attach the same class file (as a sub-class to each MovieClip), and have one for the main stage, which is where the above function would live, and I can use it to call the other MovieClips, Images or whatever I need to call dependent on device resolution.

    Now, inside each MovieClip I drew out simple text boxes containing the text, iPhone, iPhone Retina & iPad, so when i run the app, I can see whats going on, now when I run this on a standard device, what you would expect to happen, happens, the app loads up and it says iPhone, sweet, same expected result on the iPad, the app runs and reports back that it’s an iPad, cool, now when I run this code on the iPhone Retina, something strange happens, the standard resolution MovieClip loads, it still looks good as do most 480×320 apps on a 960×640 device, because, as mentioned above, of the way Apple designed the Retina Screen’s, but hey that’s not the point on a Retina device I want to see my iPhone Retina text shown on the screen.

    So, what to do?, scream or keep going, i think you know what I choose, so after a bit more research I found this post, where it’s mentioned that you can scale down a 960×640 MovieClip or Image to fit a 480×320 screen, so I came up with this code.

    function checkRes():void
    {
    //trace(“Hello”);
    //if (xRes == 1366 && yRes == 768) {
    //Landscape iPad Res
    if (yRes >= 1024 && xRes >= 768) {
    deviceID = “iPad”;
    deviceFork();
    }
    else if (yRes == 960 && xRes == 640)
    {
    deviceID = “iPhoneRetina”;
    deviceFork();
    }
    else if (yRes == 480 && xRes == 320)
    {
    this.scaleX = 0.5;
    this.scaleY = 0.5;
    deviceID = “iPhone”;
    deviceFork();
    }
    }

    The code now works on all three device’s, as if the device has a standard resolution the Retina MovieClip still loads but is scaled by half, so now my iPad says iPad, my Retina iPod says Retina, and my standard iPod also says Retina because it’s my perfectly scaled 960×640 MovieClip, as you will notice i have also split up the checkRes function, and added a string variable called deviceID, which if I need to, I can use for repositioning elements, or for telling my code to do something different depending on the device, of course I could have used an integer, but strings are much more readable.

    Next I created a new function called deviceFork, which uses the deviceID string to load one of three functions dependent on the device, which was originally determined by checking the screen resolution, and inside each of the three device dependent functions, I now load the appropriate MovieClip. I am still in the very early stages of testing, however initial tests are proving to be working, long, long way to go yet though, as mentioned above I first need to re-size all of my App images so I can test on ScaleViz 😉

    So that’s what I’m up to, hope that helps, got to sleep now.

    ———————————————– Edit ————————————————

    Seeing as there has been a request for the deviceFork function, here is a paste of the complete class, you can also download the fla at the end of this post, password is the same as usual so if you’ve already subscribed, you know what to do.

    package
    {

    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.system.Capabilities;
    import flash.display.MovieClip;

    public class MultipleDisplay3 extends MovieClip
    {

    var xRes:Number;
    var yRes:Number;
    var box:MovieClip;
    var deviceID:String;

    public function MultipleDisplay3()
    {

    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = StageAlign.TOP_LEFT;
    xRes = Capabilities.screenResolutionX;
    yRes = Capabilities.screenResolutionY;

    checkRes();
    }

    function checkRes():void
    {
    //trace(“Hello”);
    //my laptop res unrem for testing
    //if (xRes == 1366 && yRes == 768) {
    //Landscape iPad Res
    if (yRes >= 1024 && xRes >= 768) {
    deviceID = “iPad”;
    deviceFork();
    }
    else if (yRes == 960 && xRes == 640)
    {
    deviceID = “iPhoneRetina”;
    deviceFork();
    }
    else if (yRes == 480 && xRes == 320)
    {
    //stage.scaleMode = StageScaleMode.SHOW_ALL;
    //stage.scaleMode = StageScaleMode.NO_SCALE;
    this.scaleX = 0.5;
    this.scaleY = 0.5;
    deviceID = “iPhone”;
    deviceFork();
    }
    }

    function deviceFork():void
    {
    if (deviceID == “iPad”)
    {
    trace(“woohoo iPad”);
    deviceIsAn_iPad();
    }
    else if (deviceID == “iPhoneRetina”)
    {
    trace(“woohoo iPhone Retina”);
    deviceIsAn_iPhoneRetina();
    }
    else if (deviceID == “iPhone”)
    {
    trace(“woohoo iPhone”);
    deviceIsAn_iPhone();
    }

    }

    function deviceIsAn_iPad():void
    {
    //do stuff
    trace(Capabilities.screenResolutionX);
    trace(Capabilities.screenResolutionY);
    trace(deviceID);
    box = new iPad;
    addChild(box);

    }

    function deviceIsAn_iPhoneRetina():void
    {
    //do stuff
    trace(Capabilities.screenResolutionX);
    trace(Capabilities.screenResolutionY);
    trace(deviceID);
    box = new iPhoneRetina;
    addChild(box);

    }

    function deviceIsAn_iPhone():void
    {
    //do stuff
    trace(Capabilities.screenResolutionX);
    trace(Capabilities.screenResolutionY);
    trace(deviceID);
    box = new iPhoneRetina;
    //box = new iPhone;
    addChild(box);

    }

    }

    }

    The images i’m using are some dude with a guitar that I drew in Illustrator, wishing he had ScaleViz ;-), these are available in the library in the Fla, and in the Zip.

    To access code samples, Click Here.
    Tutorial files were created using Flash CS5 Professional version 11.0.2.489.

    Contents of Archive (5 Files)
    MultipleDisplay.fla (No comments, See Post)
    MultipleDisplay3.as (ActionScript Class)
    MultipleDisplay.txt (Package Info)
    Guitarman-hd.png (960 x 640 png, for Retina & Standard Displays)
    Guitarman-ipad.png (1024×768 png, for iPad)

    Copyright © Shane Hogan
    Do not copy this article.

  • ADT command line compile for AS3 with Flash CS5.5 on Mac

    Been a bit quite over here for a while, that’s because I’ve been banging my head against a wall for the last few weeks trying to compile some Flash CS5.5 test apps using the new iOS 5.01 SDK.

    I searched everywhere and have been typing commands into Terminal till I’m blue in the face, I eventually figured out that, you need to change to the directory your SWF and assets are in before you type the command, DUH!, seems quite obvious now, I then thought I was on to a winner but started getting the message no such file or directory regarding the path to the 5.01 SDK, which is now here.

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk

    Note the 5.01 SDK no longer lives in your Developer directory, here is a helpful post on the subject, which also mentions that you need to be using Mac OS 10.7.3, and have Xcode 4.3.1 installed, to use the command line to build for iOS 5.01.

    A bit more searching and I also figured that the error was because Flash CS5.5 comes with Air 2.6 and you need at least version 3.1 to use the -platformsdk switch to compile your SWF for iOS, here is a great post from Adobe that tells you how to overlay AIR 2.6 with the latest version.

    And here is a post, from Adobe that has some more details on using the -platformsdk switch.

    Finally, while searching I found an excellent resource that explains these steps in detail, the book Flash iOS Apps Cookbook, by Christopher Caleb, is available from Packt Publishing, and the chapter that details compiling with the command line using ADT, is currently available for free, from Packt, although needless to say I bought the book anyway, and it is well worth the money, so if your targeting a new iPad 3 with iOS 5.01 using Flash and it’s hurting your head, support the Author and head over to Packt and buy the book (digital version is about £13.00, and comes with all necessary support code).

    Hope this saves some headaches, I certainly wish I’d found that book weeks ago, still I’ve mopped up the blood now and once it’s cleared from my eyes, I will continue development, thanks Christopher.

    Copyright © Shane Hogan
    Do not copy this article.

  • Adobe Actionscript 3 samples for Flash CS5 CS6 & CC

    I found these links a few weeks ago and wish I had found them a lot earlier, some really good sample code across categories that include interactivity, transition effects, image loading, masking and even some sample games.

    Here’s what it says on Adobes sample page

    One of the quickest ways to learn Flash Professional is to look at existing sample files to see how they are built. This page contains links to several Flash samples, with instructions on how to use them.

    Here’s the link to the AS3.0 samples page on Adobe’s site.

  • Simulating Swipes in ActionScript 3.0 to increase development workflow

    The sample code in this tutorial shows you how to simulate swipes to accelerate your mobile development. It sounds complicated but in reality is as simple as duplicating your swipe code so that it works with either button or keyboard presses, the arrow keys are the perfect candidate.

    The swipe code in ScaleViz is quite complex and this technique has saved me lots of time and headaches, so I thought I would share it with you, I’m using the test app from our last tutorial.

    As mentioned above all we need to do is simulate our swipes with the arrow keys, there are many different ways you can do the same thing in AS3, here I have chosen to use a case statement, which takes a value passed to it through a function from an event listener and compares it with the conditionals inside the case statement.

    To add this function to our test app we first add an event listener to the stage, which listens for a keyboard press and then passes the pressed key to the function called “swipeSimHandler”:

    stage.addEventListener(KeyboardEvent.KEY_DOWN, swipeSimHandler);

    Then we add the handler function that receives the pressed key from the above listener and passes it to the case statement inside the handler, which then does something depending on which key was pressed, in this case I have added in a trace statement that writes out which arrow key was pressed to your output window.

    A trace statement is an awesome feature of AS3 that you can use to write out the value of variables and messages to your output window so you know that your code is working.

    If your output window is not open then press F2 or go to “Window – output”, although it will usually open itself if there’s a message to show you.

    Here is our skeleton case statement.

    function swipeSimHandler(event:KeyboardEvent):void
    {
    switch( event.keyCode )
    {
    case Keyboard.RIGHT:
    trace(“Right Arrow Key Pressed!”)
    break;

    case Keyboard.LEFT:
    trace(“Left Arrow Key Pressed!”)
    break;

    case Keyboard.UP:
    trace(“Up Arrow Key Pressed!”)
    break;

    case Keyboard.DOWN:
    trace(“Down Arrow Key Pressed!”)
    break;
    }
    }

    Note: We can listen for any keys, they don’t necessarily have to be the arrow keys.

    For example: We could change the above case statement from Keyboard.Right, Keyboard.LEFT,  Keyboard.UP and Keyboard.DOWN to keyboard.R, keyboard.L, keyboard.U and keyboard.D , this would control our swipe code with the R, L, U and D keys, you can find the other key codes in Flash’s help, just highlight the word keyboard and press F1 while in your actions panel (F9), this will show you which other keys are available.

    Now all we need to do is copy our current swipe code and paste it into the correct place within the case statement, remembering that the swipes will be reversed on a Mobile device so we need to swap them round again. So, we paste the conditional statement from the right swipe into the keyboard left conditional and the left swipe into the keyboard right conditional, see previous tutorial for details.

    Here’s our new swipe code with the added code in bold:

    function swipeSimHandler(event:KeyboardEvent):void
    {
    switch( event.keyCode )
    {
    case Keyboard.RIGHT:
    trace(“Right Arrow Key Pressed =, Simulate Swipe Left!”)
    if(currentFrame == totalFrames)
    {
    gotoAndStop(1);
    }
    else
    {
    nextFrame();
    }
    break;

    case Keyboard.LEFT:
    trace(“Left Arrow Key Pressed – Simulate Swipe Right!”)
    if(currentFrame == 1)
    {
    gotoAndStop(totalFrames);
    }
    else
    {
    prevFrame();
    }
    break;

    case Keyboard.UP:
    trace(“Up Arrow Key Pressed!”)
    gotoAndStop(1);
    break;

    case Keyboard.DOWN:
    trace(“Down Arrow Key Pressed!”)
    gotoAndStop(3);
    break;

    case Keyboard.V:
    showTxt();
    break;
    }
    }

    We could also add another conditional inside the case statement, which as you can see I have done above, this adds a listener for the letter V which runs the function “showTxt”, when the “V” key is pressed, which toggles the visibility of text “ScaleViz Rocks!” to either on or off, so not only can you use this technique for simulating your swipes you can also use it to add in keys to work various parts of your app that could rely on the swipes performing a certain function.

    You can now run your test app within flash using the arrow keys to simulate your swipes and you know that when you are ready to deploy your app for testing on your device everything will work as you expected, just remember to swap the left and right code back again.

    As you can see this is a massive time saver when your app relies on swipes as you don’t have to keep deploying it to your device to test if your latest code change is working as it should.

    To access code samples, Click Here.
    Tutorial files were created using Flash CS5 Professional version 11.0.2.489.

    Contents of Archive (2 Files)
    simulateSwipe.fla (fully commented test app)
    simulateSwipe.txt (info)

    Copyright © Shane Hogan
    Do not copy this article.