logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
May 21, 2012
The Math and ActionScript of...
We see lines used in a lot of scenarios; curves are also used but perhaps not as frequently – but that doesn’t undermine their importance! In this tutorial we shall take a closer look at...
read more
May 20, 2012
Weekend Lecture: Understandi...
Interested in game design? This weekend, we feature a set of four interactive lectures: games that are about game design, by Pixelate. Play the Games Bub and Bob, two little 8-bit guys, will talk...
read more
top
Apr 16, 2012 Posted on Apr 16, 2012 in Hints and Tips | 10 comments

Unveiling the All-New Tuts+ Hub

Over the past few weeks, we’ve been working hard behind the scenes to create a central place for our Tuts+ readers to call “home”. Somewhere that shows you the latest content from across all our sites, allows you to filter only those tutorials that interest you, and shares a few statistics about the Tuts+ network.

Today, we’re very excited to introduce the Tuts+ Hub — read on to find out more about it!


All Our Latest Tutorials in One Place

The Tuts+ Hub is a new way to see all the latest content across our whole network. Any new tutorials that have been published since your last visit will be given a “New” banner, and you can quickly filter out the sites that don’t interest you — just toggle the checkboxes at the top of the screen to show/hide content for each site.

Tuts+ Hub

We’re also showcasing all our new Tuts+ Premium tutorials — these are shown with a yellow border, so it’s worth keeping an eye out for these if you’re one of our awesome Tuts+ Premium members!


A Handful of Statistics

We also thought it would be fun to share a few of our statistics with you. Did you know we’ve published over 11,500 tutorials? Or that we’re approaching half a million comments across the network? It’s a fun way to keep an eye on how Tuts+ is growing (and these stats are updated every day).

Tuts+ Hub

What Do You Think?

I’d love to hear your feedback on Tuts+ Hub, and any thoughts or comments on what works well/what you’d like to see improved. We’re really happy with how the project turned out and I think you’re going to love it!

Thanks for being one of our readers and, if you’ve somehow resisted all the way down to this point, head over and check out the Tuts+ Hub!



View full post on Activetuts+

Apr 15, 2012 Posted on Apr 15, 2012 in Hints and Tips | 10 comments

Create a Flash “Alphabet Soup” Wordsearch Game – Tuts+ Premium

In this Premium Flash tutorial, you’ll learn how to create a simple wordsearch with a neat “highlighter” interface, which is easy to modify with your own words and layout. It’s a neat diversion you could add to any website, or something you could extend to make into a full game.


Premium Preview

Let’s take a look at the result we will be working towards:

In this tutorial we’ll use a series of ActionScript classes to create a classic Alphabet Soup wordsearch game. The objective of the game is to highlight letters to form a word. You will be able to create your own alphabet soup and include your own words.


Read the Full Tutorial

Premium members can access the full tutorial right away!

If you’re not yet a Premium member, you can still read the first few steps for free.


Tuts+ Premium Membership

We run a Premium membership system which periodically gives members access to extra tutorials, like this one, from across the whole Tuts+ network. If you’re a Premium member, you can log in and read the tutorial. If you’re not a member, you can of course join today!

Also, don’t forget to follow @envatoactive on twitter, circle us on Google+, like us on Facebook, and grab the Activetuts+ RSS Feed to stay up to date with the latest tutorials and articles.



View full post on Activetuts+

Apr 13, 2012 Posted on Apr 13, 2012 in Hints and Tips | 10 comments

Quick Tip: Configuring TextMate for Dart Coding

Dart is a pretty cool new language that could mean a change in the way you write web applications. Google provides an Eclipse-based Dart Editor that provides a handy means to get started. But TextMate users usually find a way to bend TextMate to their will, and this Quick Tip will get you started a-bending to use Dart with TextMate.


Prerequisites

I assume you are familiar with TextMate bundles to at least the degree of what they are and that they add functionality (usually language-specific) to TextMate. I also assume you are familiar with and are capable of checking code out of a Subversion repository. Lastly, I assume you have a little Dart experience. You don’t need much, but having some Dart files around to open in TextMate will make this go much smoother.

If you’re not familiar with Dart at this point, I can point you to the official source of information: http://www.dartlang.org/. Beyond that, Activetuts+ has previously published my introductory tutorial on the language, What is Dart, and Why Should You Care?


Install Dart Editor

We won’t really be using the Dart Editor (the point of this tutorial is to use TextMate for Dart development), but the download includes the Dart SDK, which is really what we’re after. Even if you’re a hardcore TextMate fanatic (like I am), it’s still not a terrible idea to have the “official” Dart Editor installed and handy.

On the official Dart site (see the previous section), you can download the Dart Editor from the following link: http://www.dartlang.org/docs/getting-started/editor/index-macos.html

If you’re on Windows or Linux, yet are reading this tutorial despite its Mac-centric nature, you can download the Dart Editor for those platforms from the Dart Editor for Windows and Linux pages.

Under “Step 1” of that page, you’ll find a link to a ZIP file containing the Dart Editors. It’s around 40 MB, so it’s not a terribly heavy download.

The Dart Editor is based on Eclipse, so if you’ve used that you’ll be right at home with the Dart Editor. I won’t be getting into details on using it in this tutorial, but feel free to play around with it. The current Activetuts+ Facebook Fan Bonus takes you through the basic usage of the Dart Editor.

(Note that if you don’t want to install the Dart Editor, you can download just the Dark SDK for your OS at this URL (it’s only 2 or 3 MB): http://www.dartlang.org/docs/getting-started/sdk/index.html


Install frogc

frogc is the Dart-to-JavaScript compiler. It’s a command line tool, but it’s thankfully easy to use. We’ll be using it in a TextMate command later to turn our Dart file(s) into JavaScript so we can actually use our Dart code today.

Open up Terminal (found in your /Applications/Utilities/ folder). Type the following:

nano ~/.bash-profile

If you already have some PATH customizations going on, place your cursor after these lines.

Type:

export PATH=$PATH:

And then drag the bin folder, which should be located at /Applications/dart/dart-sdk/bin, into the Terminal window. If it’s not in that location, look for a dart-sdk folder in something that you downloaded (if you downloaded the SDK by itself, this should be that download, unzipped). You should end up with something like this:

export PATH=$PATH:/Applications/dart/dart-sdk/bin

To save this file, press Control-O (that’s Control, not Command), press Return to confirm the file to save, and then press Control-X to exit nano.

Almost ready; I’ve found a problem with frogc if you happen to have spaces in your file or folder names. This can be easily fixed, though. Open up frogc. It’s an executable shell script, so don’t double-click it. Instead, drag it to your TextMate icon, and you may be presented with a warning dialog but you should be able to see the short script. You don’t need to understand what this does, just change the last line from this:

$SCRIPTPATH/dart --new_gen_heap_size=128 $SCRIPTPATH/frogc.dart --libdir=$LIBPATH $@

…to this:

"$SCRIPTPATH/dart" --new_gen_heap_size=128 "$SCRIPTPATH/frogc.dart" --libdir="$LIBPATH" "$@"

Notice that basically I’ve surrounded every path with quotes, which helps avoid the space problem.


Install Google’s Dart TMBundle

You can find the .tmbundle on this Google Code page.

You can either check out the entire Dart source, which might be interesting to poke through, or you can simply check out the .tmbundle. Using the Terminal, navigate to the location in which you’d like to have the code (type cd then drag the destination folder into the Terminal window again — note that there’s a space after cd). Once Terminal is in your desired location, type this is in for a full checkout:

svn checkout http://dart.googlecode.com/svn/trunk/ dart-read-only

…or this for just the .tmbundle:

svn checkout http://dart.googlecode.com/svn/branches/bleeding_edge/dart/tools/utils/textmate/Dart.tmbundle

If you’ve checked out the entire project, you can navigate to the .tmbundle by following this path from the project root: [dart-read-only]/dart/tools/utils/textmate/Dart.tmbundle. Either way, double-click on the .tmbundle to have TextMate install it.

A lot of TextMate users like to simply check .tmbundles out directly to their bundle directory. To do this, navigate to that directory in Terminal (this should do it: cd "~/Library/Application Support/TextMate/Pristine Copy/Bundles") and then run the second svn checkout line above (the one that checks out just the .tmbundle). This way you can easily update the bundle in-place with svn up "~/Library/Application Support/TextMate/Pristine Copy/Bundles".


Write a Command to Compile Dart to JavaScript

The Google Dart Bundle is great for adding syntax support for Dart, so when you create a file ending in .dart you get colored syntax and code folding and that sort of thing. But it doesn’t include any snippets or commands. The most useful command (indeed, the first thing I thought of) is a command to compile your current Dart script with frogc for you. We’ll add one in this step.

In TextMate, open the Bundle Editor (press Command-Option-Control-B, or go to Bundles > Bundle Editor > Show Bundle Editor)

Click on the Dart entry in the left-hand list.

With the “+” button at the bottom left, choose “New Command”.

You should see a new “untitled” command appear under the Dart bundle. Rename it to “Compile with frogc”

In the large text area on the right (labeled “Command(s)”), enter the following:

frogc "$TM_FILEPATH"

Above the text area, you have the option of having the command save the file before running. This might appeal to you (it does to me; one less keystroke!). If it does, then change the “Save” option from “Nothing” to either “Current File” or “All Files in Project”.

Underneath the text area, where it says “Input,” set it to “None”.

Below that, where it says “Output,” set it to “Show as Tooltip”. This lets any output from the command show up in a tooltip near the cursor, which means if you have errors while running frogc you can see them. They’re not terribly pretty but it’s better than nothing.

Below that, where it says “Activation,”, make sure it’s set to “Key Equivalent” then put your cursor in the text field to the right. Type Command-B; this sets this command to trigger when you type that keyboard shortcut. Command-B is the TextMate idiom for a Build command if bundles have one.

Below that, where it says “Scope Selector,” type “source.dart#8221;.

Your command window should look something like this:

The completed frogc command

Close the Bundle editor window.


Step 1: Tell TextMate Where frogc is

We’ve set up Terminal so that it knows where frogc is, but unfortunately TextMate does not share that information. The easiest solution is to add the path that we added to the .bash_profile file to your Textmate preferences.

Open up TextMate’s Preferences (press Command-, or go to TextMate > Preferences…).

Click on the Advanced button at the top, then click on the Shell Variables tab.

The Shell Variables preference

If you don’t already have a PATH variable, click the “+” button and, in the first column, type PATH.

In the second column of the row that begins PATH, type the path you added to the .bash_profile (just the path, not the part that says EXPORT PATH=@PATH:). Be sure to leave the existing value intact — add a colon at the end of what’s there already, and then copy in the new path.

Close the Preferences window, and you’re ready to try it out. If you need a Dart file, you can either create a Hello World file by creating a new project with Dart Editor, or you can dig up the examples from the Dart Editor download, in the “samples” folder. Open up a Dart file in TextMate and hit Command-B; if all goes well you should have a JavaScript file next to the Dart file after a few seconds.


Step 2: Get Feedback From frogc

If you’d like to get a little fancier, you can change the code of your compile command to this:

result=`frogc "$TM_FILEPATH"`
if ["$result" == ""]; then
    echo "Compile completed"
else
    echo $result
fi

This will give you a “Compile completed” tooltip once frogc is done running, if it runs successfully. If you have errors, they’ll still show up as they did before.

One other option: if you liked the idea of automatically saving files when running the command, you might like the idea of replacing the Save command with a Save-and-Compile command. This is as simple as changing Command-B to Command-S, and making sure you’re saving the “Current File” in the command. This overrides the regular Command-S, which simply saves the current document, with the execution of this command, which saves and then compiles.

For completeness, you can create a duplicate command that saves “All Files” and has an activation key of Command-Option-S. This shortcut will override the regular Command-Option-S in TextMate, which normally saves all files in a project. Note that because you’ve set a Scope Selector, this override will only happen in Dart files, not every time you save any file.


Start Building Snippets

There are potentially many useful snippets to be added to a Dart bundle. Generally I find myself incrementally adding them as I get to know a language and discover that the existing .tmbundle doesn’t already include one. Let me get you started by adding a snippet that creates a new method.

In the Bundle Editor, make sure the Dart bundle (or an item in the Dart bundle) is selected, then choose “New Snippet” from the “+” button. Name it “method”.

In the large text area, select all the existing text and delete it. Now enter (or paste) the following:

${1:void} ${2:methodName}(${3:arguments}) {
    $0${1/void|(.+)/(?1:\n\treturn null;)/}
}

Under “Activation,” set the pop-up to “Tab Trigger” and enter method in the text field (feel free to change this).

Under “Scope Selector,” type in source.dart.

Your snippet should look like this:

The completed method snippet

Close the Bundle Editor.

Try it out. In a Dart file, type “method” (or whatever you specified, if you forged your own tab trigger), press Tab, and watch it expand. You can tab through the various stops, starting at the return type, then to the method name, and finally in between the parentheses if you want to add arguments. The last tab will drop you at the first line of the method.

The cool part is that if you change the return type from void, you get an automatic return null statement at the end of your method body. Naturally you’ll want to adapt this to your needs, but hopefully it’s a feature that saves a little typing. The magic happens in the unwieldy second line of the snippet; if you’ve never seen this before, then it’s somewhat difficult to explain concisely, but it looks at the contents of the first tab stop (the return type) and if it’s anything other than “void”, it adds the return null. It might make sense if you’ve ever used Regular Expressions, particularly with the substitution syntax of /pattern/substitute/ found in Perl.

Given that Google provides no snippets with their .tmbundle, the field’s wide open for the creation of time-saving Dart snippets. Feel free to post your snippets in the comments. We’ll compile them and see if we can get Google to incorporate them into their official bundle.


That is All

Thanks for reading! I hope you are as excited about Dart as I am. And the Dart Editor is neat and everything, but I’m a fool for TextMate. Combining Dart with my text editor of choice is something that just had to be shared.



View full post on Activetuts+

Apr 12, 2012 Posted on Apr 12, 2012 in Hints and Tips | 10 comments

Pixel-Level Collision Detection Based on Pixel Colors

In this tutorial, I’ll follow the approach suggested by Richard Davey (Thanks, Richard!), and used by him and others, in detecting collisions between bitmaps with a subtle modification. I’ll also compare performance between various approaches of bitmap collision detection using Grant Skinner’s PerformanceTest harness.


Step 1: Overview

I describe this alternative approach in short here.

  1. Check whether there’s any overlap between the two bitmaps.
  2. If there is, proceed to #3. Otherwise, drop out.
  3. Check whether the overlap area has any opaque pixels overlapping.
  4. If so, the bitmaps overlap. Otherwise, drop out.

Step 2: Bounding Boxes

First, we check whether the two bitmaps’ bounding boxes are overlapping using Rectangle. The scripts are as below. First, the variables.

private var enemy1:Bitmap, myShip:Bitmap;
private var myShipSp:Sprite;
private var rec_e:Rectangle, rec_m:Rectangle;
private var intersec:Rectangle;
enemy1 = new E1 as Bitmap;	addChild(enemy1);
myShip = new My as Bitmap;
myShipSp = new Sprite; addChild(myShipSp);
myShipSp.addChild(myShip);

enemy1.x = stage.stageWidth >> 1;	myShipSp.x = stage.stageWidth >> 1;
enemy1.y = stage.stageHeight * 0.2;	myShipSp.y = stage.stageHeight * 0.8;

//drawing boxes around the sprite
draw(enemy1.getBounds(stage), this, 0);
draw(myShipSp.getBounds(stage), this, 0);

Here we check for any overlapping area between the boxes. Check out DetectVisible.as in the source download for the full script

private function refresh(e:Event):void
{
    //determining the bounding box of intersection area
    rec_e = enemy1.getBounds(stage);
    rec_m = myShipSp.getBounds(stage);
    intersec = rec_e.intersection(rec_m);

    //redraw the bounding box of both sprites
    this.graphics.clear();
    draw(enemy1.getBounds(stage), this, 0);
    draw(myShipSp.getBounds(stage), this, 0);

    //only draw bounding box of intersection area if there's one
    if (!intersec.isEmpty()){
        lines.graphics.clear();
        draw(intersec, lines);

        t.text ="Intersection area by red rectangle."
    }
    else {
        t.text ="No intersection area."
    }
}

Here’s a demo. Drag the smaller spaceship around.

(Don’t worry about the red box that gets “left behind” when the ship is dragged out of the other’s bounding box.)


Step 3: Drawing into the Intersection Area

So if there’s an intersecting box area, we proceed to check whether there are overlapping pixels in the area. However, let’s first try to draw bitmap into this intersection area. The full script’s in DetectVisible2.as

private function refresh(e:Event):void
{
    //determining the bounding box of intersection area
    rec_e = enemy1.getBounds(stage);
    rec_m = myShipSp.getBounds(stage);
    intersec = rec_e.intersection(rec_m);

    //redraw the bounding box of both sprites
    this.graphics.clear();
    draw(enemy1.getBounds(stage), this, 0);
    draw(myShipSp.getBounds(stage), this, 0);

    //only draw bounding box of intersection area if there's one
    if (!intersec.isEmpty()){
        lines.graphics.clear();
        draw(intersec, lines);

        //to draw the intersection area and checking for overlapping of colored area
        var eM:Matrix = enemy1.transform.matrix;
        var myM:Matrix = myShipSp.transform.matrix;

        bdt_intersec = new BitmapData(intersec.width, intersec.height, false, 0)
        eM.tx -= intersec.x;	eM.ty -= intersec.y
        myM.tx -= intersec.x;	myM.ty -= intersec.y

        bdt_intersec.draw(enemy1, eM);
        bdt_intersec.draw(myShip, myM);

        bm_intersec.bitmapData = bdt_intersec;
        bm_intersec.x = 10
        bm_intersec.y = stage.stageHeight * 0.8 - bm_intersec.height;

        t.text = "Intersection area by red rectangle.\n"
    }
    else {
        t.text ="No intersection area."
    }
}

Note that since we are drawing the area by the use of a matrix, any scaling, skewing and other transformations on both bitmaps are taken into account. Here’s a demo; check out the box in the bottom left corner.


Step 4: Check for Color in the Intersection Area

So how do we check for the right pixel? Well first of all, we give the color of this intersection box a shade of black (Red = 0, Green = 0, Blue = 0). Then, the shade of the smaller spaceship will painted into this dark box as green, with the blend mode of ADD. Similarly, the shade of the bigger stationary alien spaceship will be painted red.

So now, there will be areas of red and green for the spaceships, and black if there are no overlapping area. However, if there are pixels from these two bitmaps that overlap, these will be drawn in yellow (Red = 255, Green = 255, Blue = 0). We use the method Bitmapdata.getColorBoundsRect to check for the existance of this area.

Here’s the snippet in Main.as

//to draw the intersection area and checking for overlapping of colored area
var eM:Matrix = enemy1.transform.matrix;
var myM:Matrix = myShipSp.transform.matrix;

bdt_intersec = new BitmapData(intersec.width, intersec.height, false, 0)
eM.tx -= intersec.x;	eM.ty -= intersec.y
myM.tx -= intersec.x;	myM.ty -= intersec.y

//tweak color
bdt_intersec.draw(enemy1, eM, new ColorTransform(1,1,1,1,255,-255,-255), BlendMode.ADD);
bdt_intersec.draw(myShip, myM, new ColorTransform(1,1,1,1,-255,255,-255), BlendMode.ADD);

bm_intersec.bitmapData = bdt_intersec;
bm_intersec.x = 10
bm_intersec.y = stage.stageHeight * 0.8 - bm_intersec.height;

t.text = "Intersection area by red rectangle.\n"

//check for the existance of the right color
intersec_color = bdt_intersec.getColorBoundsRect(0xffffff, 0xffff00);
if (!intersec_color.isEmpty())	t.appendText("And there are interesecting pixels in the area.");

Note that we suppress the Red and Blue components in line 113 to max out Green for the small spaceship. On line 112 we do the same with the alien spaceship with the Blue and Green components.


Comparing Approaches

So after receiving comments on performance issues regarding collision detection, I decided to do some quick and dirty tests on these approaches. I created 20 enemy spaceships and one player spaceship and checked collision detection between that one player ship against the other 20. These sprites are packed into the same vicinity to force collision detection for all approaches to have a complete run.

The first approach is the simplest. BitmapData is captured on initiation and for each frame, collision detection is checked using BitmapData.hitTest(). For the second approach, BitmapData is updated each frame and collision detection is done based upon those BitmapData captured. The third one refers to the approach suggested by this tutorial.

So the result for one of the tests I’ve done is as below.

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
bitmapdata fixed (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
bitmapdata fixed                                            168     0.17
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
bitmapdata updates (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
bitmapdata updates                                         5003     5.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
custom method (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
custom method                                              4408     4.41
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

The PerformanceTest gives different results whenever I run test. So I ran it a few times and derived an average time. Conclusion: the fastest method is the first, followed by the third and then the second approach.

So storing away BitmapData for bitmaps when they are first introduced into stage and checking for hitTest every frame after is actually efficient, provided these sprites don’t perform any transformations other than translation (such as rotation, skewing and scaling) across time. Otherwise, you will be forced to adopt either the second or third approach, and the third one is more efficient as indicated by the image above.

You may check out Collisions.as and Results.as for the full script.


Searching for Expensive Methods

I embarked thereafter to search for the specific lines of code that took up more computation time. The second and third approach took more time, so I derived several functions from them, each breaking at different points. Check out one of the results below.

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
default hitTest (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
include bounds
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
default hitTest                                             189     0.19
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
default hitTest (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
include transform
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
default hitTest                                             357     0.36
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
default hitTest (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
include hittest
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
default hitTest                                            4427     4.43
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
custom method (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
inlcude bounds and transform
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
custom method                                               411     0.41
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
custom method (1000 iterations)
Player version: WIN 11,1,102,55 (debug)
include draw and bounds
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
custom method                                              3320     3.32
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

The first, second, and third times refer to the second approach at different breakpoints, and the fourth and fifth times refer to the third approach. Looking at the third and the fifth time results, BitmapData.draw seems to take a lot of computation time. And the time taken for drawing with the second approach seems to be more expensive in computation time, which leads me to think that the sizes for BitmapData.draw to operate on does matter. You may check out Collisions2.as and Results2.as for the full scripts.

One thing I find a little disturbing is the inconsistency of these tests – I always don’t get the same time results, although they almost follow the same ranking at all times. So, its good enough to do some simple comparison between functions.

Conclusion

Well, thanks for your time looking reading this little tip. Hope it has been useful. Do leave comments if you don’t agree with anything in this tutorial. I’d love to respond to feedback!



View full post on Activetuts+

Apr 12, 2012 Posted on Apr 12, 2012 in Hints and Tips | 10 comments

Accessing the Same Saved Data With Separate Flash and JavaScript Apps

In this tutorial I will show you how to access the same saved data in separate Flash and JavaScript apps, by storing it in HTML5 LocalStorage and using ExternalInterface to reach it with AS3. We will create the same app in both JavaScript and Flash to demonstrate that it is platform agnostic.


Step 1: Examining Local Storage

Local Storage is an exciting part of HTML5 that allows you to do browser side storage that is persistent, meaning it lasts between browser sessions. It only disappears when the user clears their browser cache.

It is a very easy API to use, using simple key-value pairs to store data, and can be used in a few different ways. One way is to use localStorage.setItem('key','value'), and localStorage.getItem('key'). Another way is to use Object Notation: localStorage[key] = value to set a value, and theValue = localStorage[key] to retrieve it. And, if that wasn’t enough, there is yet a third way – Dot Notation: localStorage.key = value to set it, and theValue = localStorage.key to retrieve it.

I am opting for the third way in this tutorial, but if you prefer one of the other ways you can modify the code and it should work just fine. Local Storage does have a few other methods, but these are the only two methods we need: one to set a value and one to retrieve that value.


Step 2: Setting Up the JavaScript Project

We will create the JavaScript app first. You should develop both this and the Flash project on a live server, otherwise you will run into problems. I am using WAMP on my machine as a local hosting environment.

Create a folder to store your project in. Within this folder create two new folders. Name one of them “js” and the other “styles”.

Within the “styles” folder create a new file and name it “style.css”, and within the “js” folder create a new file and name it “externalinterface.js”. Finally, at the root of your project folder create a new file and name it “index.html”.


Step 3: The Index HTML Page

Enter the following code within the “index.html” file you created in the step above.

<!DOCTYPE html>
<html>
<head>
<title>Local Storage with external Interface</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" />
<script type="text/javascript" src="js/externalinterface.js"></script>
</head>
<body>
<div id="wrapper">
<div id="scorewrapper">
<p id="scorediv"></p>

<p id="randomscorediv">Random Score is: </p>

<button type="button" id="scorebtn">Generate Score</button>
</div>

</div>

</body>
</html>

Here we set up the structure of our “index.html” file. We include the “style.css” and the “externalinterface.js” we created in the step above. The scorediv will be updated when we achieve a new high score, and the randomscorediv will be updated each time we generate a new score (click on the button to generate a random score).


Step 4: style.css

Enter the following within the “style.css” you created in the step above.

#wrapper{
	width:400px;
	height:400px;
	margin: 0 auto;

}
#scorewrapper{
	width:400px;
	height:200px;
	background-color:#FFFFFF;
}

#randomscorediv{
	visibility: hidden;
}

body{
	background: #f2f2f2;
	text-align: center;
	padding: 20px;
}

Here we set the app to be centered in the page, set the background-color of the scorewrapper div, and set the randomscorediv to initially be hidden (invisible). When we click on the button we will set the randomscorediv to visible.


Step 5: window.onload

Enter the following code within the “externalinterface.js” you created in the step above.

window.onload = function(){
alert("Window Loaded");
}

Whenever you need to tie into elements on your web page you should make sure the window has loaded first. Since we need to tie into the button, we use the window.onload function provided by JavaScript. Here we are just popping up an alert with the words “Window Loaded”. If you test the page you should see it is working.


Step 6: setScore()

In this step we will code the setScore() function that initially sets the score to 0. Enter the following code within the “externalinterface.js”.

window.onload = function(){
	function setScore(){
		if(!localStorage.score){
			localStorage.score = 0;
		}
	}
}

Here we check whether the localStorage.score exists, and if it doesn’t we initialise its value to 0. When the user first runs the app, or after they clear their cache, this value would not exist – so we need to create it.

Now call this function immediately after you create it, and test by putting it in an alert.

window.onload = function(){
	function setScore(){
		if(!localStorage.score){
			localStorage.score = 0;
		}
	}
	setScore();
	alert(localStorage.score);
}

Step 7: getScore()

We have a way to set our score, now we need a way to retrieve it. That is what the getScore() function will accomplish. Enter the following beneath the setScore() function you created in the step above.

function getScore(){
	if(localStorage.score){
		return(localStorage.score);
	}
}

Here we check that localStorage.score does exist, and if it does we simply return the value it holds. Remove the alert from the previous step, and add the following alert beneath the getScore() function.

function getScore(){
	if(localStorage.score){
		return(localStorage.score);
	}
}
alert(getScore());
}

If you test now you should see the alert again showing the score of “0″.


Step 8: updateScore()

Now that we have a way to set and get our score, we need a way to update it. That is exactly what the updateScore() function achieves. Add the following beneath the getScore() function you created in the step above.

function updateScore(newScore){
	if(localStorage.score){
		localStorage.score = newScore
	}
}

Here we pass as a parameter a newScore; we then set the localStorage.score equal to this value. Remove the alert from the previous step, then add the following beneath the updateScore() function you just created.

function updateScore(newScore){
	if(localStorage.score){
		localStorage.score = newScore;
	}
}
updateScore(10);
alert(getScore());

If you test now, you should see “10″ being alerted, since on line 6 we updated the score to 10.


Step 9: showScore()

Now that we have all our methods in place to manipulate the score, let’s get it showing. Enter the following beneath the updateScore() function you created in the step above.

function showScore(){
    var scoreText = document.getElementById('scorediv');
    scoreText.innerHTML = "Current High Score is "+getScore();
}

Here we get a reference to the scorediv, and alter its innerHTML property to show the current score.

Call this function immediately after you create it.

function showScore(){
    var scoreText = document.getElementById('scorediv');
    scoreText.innerHTML = "Current High Score is "+getScore();
}
showScore();

If you test the page now you should see the words “Current High Score is 10″.


Step 10: Getting a Reference to the Button

We want to run a function when the user click on the button. Add the following beneath the showScore() button you created in the step above.

var scoreBtn = document.getElementById('scorebtn');
scoreBtn.addEventListener('click',getRandomScore,false);

Here we get a reference to the button which we gave the ID scorebtn. We then add an EventListener of type click, which calls the getRandomScore() function that we will create in the next step.


Step 11: getRandomScore()

The getRandomScore() function is where the logic of this application takes place. Add the following beneath the line scoreBtn.addEventListener('click',getRandomScore,false); you entered in the step above.

function getRandomScore(){
	var randScoreText = document.getElementById('randomscorediv');
	randScoreText.style.visibility='visible';
	var randScore = Math.floor(Math.random()* 200000);
	var currentScore = Number(getScore());
	randScoreText.innerHTML = "Random Score is "+randScore;
	if(randScore > currentScore){
		alert("New High Score!!");
		updateScore(randScore);
		showScore();
	}
}

Here, we first get a reference to the randomscorediv and set it to be visible. We then generate a random score by calling Math.floor(Math.random()* 200000), which creates a number between 0 and 200,000. We use our getScore() function to set the variable currentScore (making sure we cast it to a Number), and set the innerHTML of the randScoreText to the randScore.

Lastly we check whether randScore is greater than currentScore, and if it is we show an alert("New High Score!!") and then update the localStorage.score by calling our updateScore() method and passing in the randomScore. We then use showScore() to show the new score.

This concludes the JavaScript application – you can test it here. In the next step we will start devloping the Flash version.


Step 12: Setting Up the Flash Project

In this step we will set up the Flash project.

Create a folder to store your project files in. Now inside this folder create a folder named “js”, and within this folder create a file and name it “externalinterface.js”. At the root of your project folder create a file named “index.html”. Lastly, create a new Flash Project and save it in the root folder, making sure you name it “externalInterface.fla”. Give it a white background, and set the size to 400x200px.


Step 13: Setting Up the Index Page

Add the following to the “index.html” file you created in the step above.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tuts+ Premium: Demo</title>
<style>
	body {background: #f2f2f2;  text-align: center; padding: 20px}
</style>
<script type="text/javascript" src="js/externalinterface.js"></script>
</head>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="400" height="200" id="externalInterface" align="middle">
  <param name="allowScriptAccess" value="sameDomain" />
  <param name="allowFullScreen" value="false" />
  <param name="movie" value="externalInterface.swf" />
  <param name="quality" value="high" />
  <param name="bgcolor" value="#ffffff" />
  <embed src="externalInterface.swf" quality="high" bgcolor="#ffffff" width="400" height="200" name="externalInterface" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</body>
</html>

Here we set up our “index.html” file. We include the “externalinterface.js” we created in the step above, and embed the SWF file inside the object tag. If you decided to name your FLA something different, it is important to place the correct value for the SWF where applicable.


Step 14: Setting Up externalinterface.js

Add the following to the “externalinterface.js” you created in the step above.

function setScore(){
    if(!localStorage.score){
		localStorage.score = 0;
	}
}

function getScore(){
	if(localStorage.score){
	 return localStorage.score;

	}
}

function updateScore(newScore){
		localStorage.score = newScore
	}

These are the same functions we used in the JavaScript application, so I will not be explaining them here. It is important to note that I removed the window.onload, however.


Step 15: Setting Up the FLA

In this step we will setup the UI for the FLA you created in the steps above.

Select the Text tool and make sure the following properties are set under the “Character” panel.

  • Color: black
  • Size: 16pt

Now drag a TextField out to the stage and give it the following properties.

  • X: 102.00
  • Y: 14.00
  • W: 210.00
  • H: 25.25

Give it the instance name “currentScore_txt” and make sure the type is set to “Classic Text” and “Dynamic Text” respectively.

Now, drag another TextField onto the stage and give it the following properties.

  • X: 102.00
  • Y: 49.00
  • W: 210.00
  • H: 25.25

Give it the instance name “randomScore_text”.

Go to the Components panel, and drag a button onto the stage. (You can get to the Components panel by going to Window > Components or just by pressing CTRL + F7.)

Give the button the following properties.

  • X: 150.00
  • Y: 110.00
  • W: 100.00
  • H: 22.00

Give it the instance name “scorebtn”.

Within the “Components Parameters” panel, change the label to “Generate Score”.

Select the Rectangle tool and give it a fill color of “#CCCCCC” and no stroke.

Now, drag a rectangle out on the stage. Click to select the rectangle and give it the following properties.

  • X: 118.00
  • Y: 50.00
  • W: 173.00
  • H: 82.00

Now, right-click on the rectangle and choose “Convert To Symbol”; give it the name “alertBox”.

Double click on the rectangle to go into editing mode. Open the Components panel and drag a Button into this MovieClip. Give the Button the following properties.

  • X: 37.00
  • Y: 52.00
  • W: 100.00
  • H: 22.00

Give it the instance name “alertBox_btn”, and change the label to read “OK”.

Drag a TextField into the MovieClip and give it the following properties.

  • X: 29.00
  • Y: 10.00
  • W: 131.00
  • H: 22.00

Type the words “New High Score!!” into the TextField, then close this MovieClip.


Step 16: Main.as

Create a new ActionScript file and save it as “Main.as”. Then, back in your FLA, set Main to be the Document Class.


Step 17: Package and Imports

Add the following within the “Main.as” file you created in the step above.

package  {
	import flash.display.Sprite;
	import flash.events.*;
	import flash.external.ExternalInterface;

	public class Main extends Sprite {

		public function Main() {

		}
	}
}

Here we import the classes we will need, and code our constructor function.


Step 18: ADDED_TO_STAGE

Add the following within Main().

public function Main() {
	addEventListener(Event.ADDED_TO_STAGE,setup);
}

The ADDED_TO_STAGE event runs when the movie has fully loaded. Here it calls a setup function, which we will create next.


Step 19: The setup() Function

Add the following beneath the Main() constructor function.

private function setup(e:Event):void{
	trace("MOVIE READY");
}

If you test now you’ll see that “MOVIE READY” is traced in the output panel.


Step 20: Hiding the Alert Box

You may have noticed the Alert Box we created was showing when the movie first starts; let’s hide it. Enter the following within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
}

Here we set the alertbox to not be visible. Go ahead and test the movie.


Step 21: setScore()

In this step we will use the External Interface class to call our setScore() function that we set up in the JavaScript code. Enter the following beneath the setup() function you created in the steps above.

private function setScore():void {
    ExternalInterface.call("setScore");
}

Here we use the call() method of the ExternalInterface class to run the setScore() function that is in our JavaScript code. The call() method takes as a parameter the name of the JavaScript function to run (as a string). If we had parameters in our setScore() function, we would have included them here too.

We want this function to run when the movie first starts, so add it to the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	setScore();
}

Step 22: getScore()

In this step we will get the score to show in our Flash movie. The JavaScript will be sending the score to Flash, and to do this we will use the External Interface method addCallback() to make the function accessible to it.

Add the following within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	setScore();
	ExternalInterface.addCallback("getScore", getScore);
}

The addCallback takes two parameters: the name of a function that you want to make accessible via JavaScript (as a string), and an AS3 function that this call will be linked to (as an AS3 function callback). Here we want to make the AS3 getScore() function available to our JavaScript code first; for simplicity’s sake we give it the name getScore() when accessed via JavaScript as well.

We will now code this getScore() AS3 function. Add the following beneath the setScore() function you created in the step above.

private function getScore(score:String):int{
	var theScore:int = int(score);
	return theScore;
}

Here we set up our getScore() function. Since we will be receiving a string back from the JavaScript, we set the parameter as a string, and we return an integer. Inside this function we set up a variable named theScore and cast it to an int; we then return theScore.


Step 23: showScore()

In this step we make the current score display in the Flash movie. Enter the following beneath the getScore() function you created in the step above.

private function showScore():void{
	currentScore_txt.text = "Current High Score is: "+ExternalInterface.call("getScore");
}

Here we set the currentScore_txt.text to display the current score. We use ExternalInterface.call("getScore") to call the getScore function in the JavaScript code, which in turn triggers the getScore() function in our ActionScript code. Remember, this returns the score.

Now add the following within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	ExternalInterface.addCallback("getScore", getScore);
	setScore();
	showScore();
}

If you test the movie now, you should see the score being shown.


Step 24: addButtonListeners()

We need a way to add some listeners to our buttons, so that when the user clicks on them they do something. Add the following beneath the showScore() method you created in the step above.

private function addButtonListeners():void{
	scorebtn.addEventListener(MouseEvent.CLICK,getRandomScore);
	alertBox.alertBox_btn.addEventListener(MouseEvent.CLICK,hideAlertBox);
}

Add the following highlighted line within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	setScore();
	ExternalInterface.addCallback("getScore", getScore);
	showScore();
	addButtonListeners();
}

Here we set up our scorebtn to call an AS3 function named getRandomScore(), and we set up the alertBox_btn that is within the alertBox to call an AS3 function named hideAlertBox(). Next we will add these functions.

Add the following beneath the addButtonListeners() function you just created.

private function getRandomScore(e:MouseEvent):void{

}

private function hideAlertBox(e:Event):void{
	alertBox.visible = false;
}

We will finish the getRandomScore() function in the next step. All we do in the hideAlertBox() function is set the alertBox to not be visible. We will be making it visible when the user gets a new high score.


Step 25: getRandomScore()

In this step we will code the getRandomScore() function, where – just like in the JavaScript application we made – all the app’s logic takes place. Add the following within the getRandomScore() body you created in the step above.

private function getRandomScore(e:MouseEvent):void{
	var randScore:int = Math.floor(Math.random()* 200000);
	var currentScore:int = ExternalInterface.call("getScore");
	randomScore_text.text = "Random Score is: "+ randScore.toString();
		if(randScore > currentScore){
		alertBox.visible = true;
		ExternalInterface.call("updateScore",randScore);
		showScore();
	}
}

This works in a very similar way to the JavaScript version. We first generate a number between 0 and 200,000. Then we get the current score by using ExternalInterface.call("getScore"). We set randomScore_text to read out the random score. Lastly we check whether randScore is greater than currentScore, and if it is we show the Alert Box, update the score in Local Storage by using ExternalInterface.call("updateScore",randScore), and call our showScore() method to show the new score.

Check out the demo.


Conclusion

We have used External Interface to access the Local Storage API from HTML5. I hope you have found this tutorial useful and thanks for reading!



View full post on Activetuts+

Page 6 of 253« First«...45678...203040...»Last »
search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • The Math and ActionScript of Curves: Drawing Quadratic and Cubic Curves
  • Weekend Lecture: Understanding Games, a Flash Game About Game Design
  • Weekend Lecture: Understanding Games, a Flash Game About Game Design
  • Workshop Coding Challenge: Fix This Breakout Game
  • Enable the Latest AIR SDK in Flash Professional CS5.5+
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character Create Creating Critique Custom design Effect Effects Files Flash from Game Guide HTML5 Introduction Macromedia Motion Muzzle part Player Premium Professional Quick Silverlight Simple Text Tool Tutorial Tuts+ Tween Using Video website Workshop
About Our Site:

Hey there and welcome to "Flash Video Training Source", a resource for anybody interested in learning more about Adobe's great tool. We feature educational videos, which will help you master Adobe Flash and help you get to know all of its features. We at "Flash Video Training Source" believe that video training and video... more

Why don't you follow us on Twitter and get the latest video tutorials twitted to your account. Just click on the floating twitter bar to your right!

Go Back In Time
May 2012
M T W T F S S
« Apr    
 123456
78910111213
14151617181920
21222324252627
28293031  
Pretty Blank Box
top

Blogroll

  • Development Blog
  • Documentation
  • Plugins
  • Suggest Ideas
  • Support Forum
  • Themes
  • WordPress Planet

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Archives

  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
Powered by WordPress  |  Designed by Elegant Themes  |  Lightning Fast Hosting by Site 5 Hosting