The Ultrashock Ultra Bundle
  • Home
  • Community
  • Forum
  • Flash
  • ActionScript
  • Thread
  •  
  • Previous topic
  • Next topic
Sign up to post

Flash
 ActionScript

  • Nutrox Author 
    • 14699 
    • 0 
    • 45 
    ActionScript Tips Thread

    Last reply Sep 15 2007, 08:34 AM

    by Codemonkey

    Posted: Nov 04 2006, 06:50 PM

    by Nutrox

     


Inspired by senocular’s impressive “ActionScript 3 Tip of the Day” thread over at the Kirupa forums, I thought I would start something similar here at Ultrashock.

I will try to add an ActionScript tip, code snippet, example, etc, at least once a day to this thread and a few classes might also make an appearance. The ActionScript will range from AS2 to AS3 and may even include some prototype related snippets (even though I’m not keen on them).

I would like to try and keep this thread as tidy as possible (unlike the Full Screen Flash thread big grin), so please post any comments or questions in the ActionScript Tips Discussion thread.

smilie

Update
Our very own Codemonkey is now joining in with the fun, so expect this thread to expand quite rapidly.

Go monkey go monkey go! big grin

  45 REPLIES
  • of
  • 3
next last page
Nutrox Author 
1  
Nutrox


If you ever need to remove all of the movie clips on a timeline you could use the following function. Keep in mind that this will only remove movie clips that have been added using attachMovie, createEmptyMovieClip, or duplicateMovieClip.

[as]function removeChildren(parent:MovieClip):Void {
var i:String;
for (i in parent) {
  if (parent.removeMovieClip) {
  parent.removeMovieClip();
  }
}
}

// Delete all of the movie clips in myMovieClip.
removeChildren(myMovieClip);[/as]
Instead of using typeof to check if the object is a movie clip I am simply checking if the removeMovieClip method is available in the object. This should be quicker than using typeof.

  • 04 November 2006 06:50 PM
  •  
Nutrox Author 
2  
Nutrox


The following function will allow you to align movie clips horizontally or vertically. You can also set the amount of spacing between each movie clip.

[as]function alignClips(clips:Array, alignment:String, spacing:Number):Void {
if (spacing == null) {
  spacing = 0;
}
var hori:Boolean = alignment == “horizontal”;
var propA:String = hori ? “_x” : “_y”;
var propB:String = hori ? “_y” : “_x”;
var length:String = hori ? “_width” : “_height”;
var value:Number = clips[0][propA];
var i:Number     = 0;
var n:Number     = clips.length;

while (i < n) {
  clips[propA] = value;
  if (i) {
  clips[propB] = clips[i-1][propB];
  }
  value += clips[i++][length] + spacing;
}
}

// Create an array and populate it with the movie clips
// that we want to align.
var myClips:Array = [mc1, mc2, mc3, mc4];

// Align the movie clips horizontally with 10px spacing.
alignClips(myClips, “horizontal”, 10);

// or.. Align the movie clips vertically with 2px spacing.
// alignClips(myClips, “vertical”, 5);[/as]

  • 04 November 2006 07:14 PM
  •  
Nutrox Author 
3  
Nutrox


Normally you would link a class to a library symbol if you wanted to add a class to a MovieClip. You can however take advantage of __proto__ if you want to add a class to a movie clip at runtime.

[as]myMovieClip.__proto__ = new MyClass();[/as]
MyClass should extend MovieClip in the usual way.

The only downside to this is that physical changes to the movie clip don’t seem possible from the class constructor. For example, this._x = 0 in the following class has no effect on the movie clip.

[as]class MyClass extends MovieClip {

public function MyClass() {
  this.onRollOver = rollOverHandler;
  this.onRollOut = rollOutHandler;

  this._x = 0;
}

private function rollOverHandler():Void {
  this._xscale *= 2;
  this._yscale *= 2;
}

private function rollOutHandler():Void {
  this._xscale /= 2;
  this._yscale /= 2;
}

}[/as]

  • 04 November 2006 08:13 PM
  •  
Nutrox Author 
4  
Nutrox


If you send variables to your Flash movie using flashVars the following function could be used to gather all of the variables up into an object. Number values are converted to true numbers, and you can also name your flashVars so they are recreated as arrays.

Here’s the function:

[as]function getFlashVars():Object {
var o:Object = {};
var n:String;
var i:Number;
var s:String;
for (s in _level0) {
  if (s.substr(0,3) == “fv_”) {
  n = s.substr(3);
  if (n.indexOf(“_”) > -1) {
  i = Number(n.split(“_”)[1]);
  n = n.split(“_”)[0];
  if (o[n] == null) {
    o[n] = [];
  }
  if (isNaN(_level0[s])) {
    o[n] = unescape(_level0[s]);
  }
  else {
    o[n] = Number(_level0[s]);
  }
  }
  else {
  if (isNaN(_level0[s])) {
    o[n] = unescape(_level0[s]);
  }
  else {
    o[n] = Number(_level0[s]);
  }
  }
  }
}
return o;
}[/as]
Here are a few examples of use. Note that each flashVar name is prefixed with fv_

01 - Basic example

HTML

<param name="flashVars" value="fv_foo=hello&fv_bob=123" /> 

AS
[as]var info:Object = getFlashVars();

trace( info.foo ); // output: hello
trace( info.bob ); // output: 123
trace( typeof info.bob ); // output: number[/as]

02 - Sending Arrays

To send an array to Flash you simply add _0 _1 _2 etc to the end of your variable name.

HTML

<param name="flashVars" value="fv_items_0=apple&fv_items_1=banana" /> 

AS
[as]var info:Object = getFlashVars();

trace( info.items[0] ); // output: apple
trace( info.items[1] ); // output: banana[/as]

  • 04 November 2006 11:06 PM
  •  
Nutrox Author 
5  
Nutrox


If you want to be able to quickly and easily assign multiple functions to a movie clip’s onEnterFrame event then the following code should give you something to play with.

[as]var frameListeners:Array = [];

function addFrameListener(func:Function):Void {
removeFrameListener(func);
frameListeners.push(func);
if (!this.onEnterFrame) {
  this.onEnterFrame = fireFrameListeners;
}
}

function removeFrameListener(func:Function):Void {
var i:Number = frameListeners.length;
while (i—) {
  if (frameListeners == func) {
  delete frameListeners.splice(i, 1);
  break;
  }
}
if (!frameListeners.length) {
  this.onEnterFrame = null;
}
}

function fireFrameListeners():Void {
var i:Number = 0;
var n:Number = frameListeners.length;
while (i < n) {
  frameListeners[i++]();
}
}[/as]
With those functions placed on the movie clip’s timeline you can now add (and remove) your functions. All of the assigned functions will be called on each frame in the order you add them.

[as]addFrameListener(functionOne);
addFrameListener(functionTwo);

//

function functionOne():Void {
  trace(“function one”);
}

function functionTwo():Void {
  trace(“function two”);
}[/as]
That would result in the following trace on each frame:

—function one
—function two

Removing functions is done in the same way.

[as]removeFrameListener(functionTwo);[/as]
Keep in mind that these functions will use the movie clip’s onEnterFrame event handler so if you manually assign a function to it then things will go pear shaped. For example, you shouldn’t do something like this:

[as]addFrameListener(someFunction);

this.onEnterFrame = function():Void {
  //
}[/as]

  • 05 November 2006 09:53 AM
  •  
Nutrox Author 
6  
Nutrox


Prototype functions can be used if you want to add functions to Flash’s core classes such as String, Array, Number, and so on. When you create a prototype function, all instances of the prototyped class will be able to access the new function.

For example, let’s say that you want to be able to reverse any of your strings at any time in your movie. To do that you would add a prototype function to the String class like this:

[as]String.prototype.reverse = function() {
      var a = this.split(”“);
      a.reverse();
      return a.join(”“);
};[/as]
Now that the new function has been added you will be able to reverse any of your strings:

[as]var myText = “Hello Ultrashock”;
trace(myText); // output: Hello Ultrashock

myText = myText.reverse();
trace(myText);// output: kcohsartlU olleH[/as]
Maybe you would like to be able to shuffle any of your arrays? Easy enough, you add your function to the Array prototype object like this:

[as]Array.prototype.shuffle = function() {
var a = [].concat(this);
var i = a.length;
var n;
while (i—) {
  n = Math.floor(Math.random() * a.length);
  this = a.splice(n, 1);
} 
}[/as]
Now you can shuffle any array in your movie:

[as]var myItems = [“apple”, “banana”, “cherry”, “doughnut”];
trace( myItems ); // output: apple,banana,cherry,doughnut

myItems.shuffle();
trace( myItems ); // output: doughnut,banana,apple,cherry[/as]
You can add prototype functions to virtually any core class in Flash although it is better to create/use classes if you are able to.

  • 05 November 2006 11:16 AM
  •  
Codemonkey
7  
Codemonkey


A lot of the time while debugging/profiling, you’ll be interested in how many FPS your movie is actually pulling to see if there’s something slowing it down.

Here’s a class that let’s you specify the update interval and invokes a method each time. You can drop this class in a util folder and use it in any of your projects:

[as]
import mx.utils.Delegate;

class util.FPS {
private static var instance:FPS;
private var time:Number;
private var counter:Number;
private var interval:Number;
private var dummy:MovieClip;

public var onUpdate:Function;

public function FPS(interval:Number) {
  var d:Number = _root.getNextHighestDepth();
  this.dummy = _root.createEmptyMovieClip(“fpsmc” + d, d);
  this.interval = interval;
  this.start();
}

// reset and start measuring
public function start() {
  counter = 0;
  time = getTimer();
  dummy.onEnterFrame = Delegate.create(this, measure);
}

public function stop() {
  dummy.onEnterFrame = null;
  delete dummy.onEnterFrame;
}

// checks whether it should perform a measurement
private function measure() {
  var now:Number = getTimer();
  var lapsed:Number = now - time;
  if (lapsed >= interval) {
  onUpdate(counter * (1000 / lapsed));
  time = now;
  counter = 0;
  } 
  counter++;
}
}
[/as]

To use it:

[as]
import util.FPS;

// create FPS meter and update every 500ms
var fps:FPS = new FPS(500);
fps.onUpdate = function(fps:Number) {
trace(fps);
}
[/as]
Don’t set the interval too low though (min. 250ms) or the measurements become unreliable.

  • 05 November 2006 12:00 PM
  •  
Codemonkey
8  
Codemonkey


To quickly convert a coordination in one movieclip to another movieclip, you can use the following function:

[as]
import flash.geom.Point;

function transCoord(coord:Point, from:MovieClip, to:MovieClip):Void {
  from.localToGlobal(coord);
  to.globalToLocal(coord);
}
[/as]
This can come in handy for example when you need to move a movieclip to another movieclip that is not in the same container mc.

  • 05 November 2006 12:08 PM
  •  
Codemonkey
9  
Codemonkey


If you have an indexed array (array with 1, 2, 3, 4, ... indexes) and you want to know the index of a certain object, you can use the following function:

[as]
// returns index of an item in array, -1 if it isn’t in the array
function inArray(array:Array, item:Object):Number {
  for (var i in array) {
  if (array == item) {
  return Number(i);
  }
  }
  return -1;
}
[/as]
If you want to remove a certain object from an array and want to know whether the object was found (and so removed) you can use the following method in conjunction with the previous one:

[as]
// tries to remove an item from array and returns whether it worked
function arrayRemove(array:Array, item:Object):Boolean {
  var index:Number = inArray(array, item);
  if (index != -1) {
  array.splice(index, 1);
  }
  return index != -1;
}
[/as]
Usage:

[as]
var names:Array = new Array(“Bob”, “Shirley”, “Pete”);
trace(arrayRemove(array, “Bob”)); // traces “true”
trace(arrayRemove(array, “Bill”)); // traces “false”
[/as]
—-
You could also add these function to the Array class with prototyping as Nutrox explained in Tip 006. Or, you can add these methods to a global util class as explained in Tip 010

  • 05 November 2006 12:19 PM
  •  
Codemonkey
10  
Codemonkey


If you have some functions you might use anywhere and possibly in different projects, you might want to create util classes from them. A util class is a class available from a global path with static methods only. Flash’ Math class is a good example of this.

To create a util class start with an empty class like this:

[as]
class MyUtil {
}
[/as]
Then add your functions with the keywords public and static. Public so everyone can see them, static so everyone can access them through the classname without having to create an object first.

[as]
class MyUtil {
public static function MyUtilFunction(params_here):Number {
// do stuff with params and return result
}
}
[/as]
One benefit of having static methods only is that you acknowledge the functions do not depend on a state, which is the case a lot of the times with class instances (objects). This basically means you will only create one-shot functions that do a specific operation/calculation.

If you want to prohibit people from instantiating a utility class - which would also mean such a people didn’t ‘get’ your utility class - you can add a private constructor:

[as]
class MyUtil {
private function MyUtil() {}
}
[/as]
Here’s an example of a complete util class:

[as]
class ArrayUtils {
private function ArrayUtils() {}

// returns index of an item in array, -1 if it isn’t in the array
public static function inArray(array:Array, item:Object):Number {
      [..]
}

// tries to remove an item from array and returns whether it worked
public static function arrayRemove(array:Array, item:Object):Boolean {
      [..]
}
}
[/as]
Usage:

[as]
var names:Array = new Array(“Bob”, “Shirley”, “Pete”);
trace(ArrayUtils.arrayRemove(array, “Bob”)); // traces “true”
trace(ArrayUtils.arrayRemove(array, “Bill”)); // traces “false”
[/as]

  • 05 November 2006 12:31 PM
  •  
Codemonkey
11  
Codemonkey


To actually make your util class visible across your projects, you need to add it to your flash’ IDE. To do this, go to:
Edit->Preferences->ActionScript->ActionScript Settings button.

In there, click the button “Browse to Path” to select the folder your util class is in. For example, my global path is “D:\MyStuff\Flash\local”.

screenshot global paths

To use the global util class in your project, you can now just use a simple import statement without having to worry about whether it finds it:

[as]
// in this example ArrayUtils is in the directory/package “utils”
import utils.ArrayUtils;
[/as]

  • 05 November 2006 12:44 PM
  •  
Codemonkey
12  
Codemonkey


If you quickly need a random number in a certain range, then you can use this simple (util) function:

[as]
function randomNum(min, max):Number {
  return min + Math.round(Math.random() * (max - min));
}
[/as]

  • 05 November 2006 12:55 PM
  •  
Codemonkey
13  
Codemonkey


If you want to make sure a number is within a certain range or clip it otherwise, here’s a simple way to do this:

[as]
function clip(value:Number, min:Number, max:Number):Number {
  return Math.min(Math.max(value, min), max);
}
[/as]

  • 05 November 2006 12:58 PM
  •  
Nutrox Author 
14  
Nutrox


The following code is an example of how you could calculate the value for “bytes per second” and “remaining time” when loading external movies or images etc.

I will wrap this up in a class soon.

[as]var loadTarget:MovieClip;
var loadTimer:Number;
var loadTotal:Number;

function loadClip(target:MovieClip, url:String):Void {
loadTarget = target;
loadTimer = getTimer();
loadTotal = 0;
target.loadMovie(url);
this.onEnterFrame = updateLoadProgress;
}

function updateLoadProgress():Void {
var bLoaded:Number = loadTarget.getBytesLoaded();
var bTotal:Number = loadTarget.getBytesTotal();
if (bLoaded && bTotal) {
  if (bLoaded == bTotal) {
  this.onEnterFrame = null;
  onLoadComplete();
  }
  else if (getTimer() - loadTimer >= 250) {
  var bSec:Number = Math.round(bLoaded / (loadTotal / 1000));
  var tRemaining:Number = Math.round((bTotal - bLoaded) / bSec);
  onLoadProgress(bLoaded, bTotal, bSec, loadTotal, tRemaining);
  loadTimer = getTimer();
  loadTotal += 250;
  }
}
}

function onLoadProgress(bLoaded:Number, bTotal:Number, bSec:Number,
                tTotal:Number, tRemaining:Number):Void {
trace(“loaded progress: ” + bLoaded + “/” + bTotal);
trace(“bytes per second (approx): ” + bSec);
trace(“total time (approx): ” + tTotal + ” seconds”);
trace(“remaining time (approx): ” + tRemaining + ” seconds”);
trace(”“);
}

function onLoadComplete():Void {
trace(“loaded!”);
}

//

var container:MovieClip = this.createEmptyMovieClip(“container”, 0);
var url:String = “external.swf”;

loadClip(container, url);[/as]

  • 05 November 2006 01:10 PM
  •  
Codemonkey
15  
Codemonkey


If you are working with Forms (mx.screens.Form), you can use this enhanced version to make your screens smoothly fade in/out when showing/hiding your form:

[as]
import mx.transitions.*;
import mx.transitions.easing.*;

// use this class on your forms instead
class codemonkey.util.BasicForm extends mx.screens.Form {
private var __visible:Boolean = false;

public function BasicForm() {
  this.addEventListener(“allTransitionsInDone”, this);
  this.addEventListener(“allTransitionsOutDone”, this);
  this.createEmptyMovieClip(“bg”, this.getNextHighestDepth());
}
// display form (show/hide)
public function show(flag:Boolean) {
  if (flag != this.__visible) {
  this.__visible = flag;
  this.visible = (__visible) ? true : this.visible;
  var fadetype:Number = (flag) ? Transition.IN : Transition.OUT;
  TransitionManager.start(
this, {type:Fade, direction:fadetype, duration:1, easing:None.easeNone}
);
  }
}
// called by Flash’ transition manager
private function allTransitionsInDone(eventObj:Object) {
  this.visible = this.__visible;
}
private function allTransitionsOutDone(eventObj:Object) {
  this.visible = this.__visible;
}
}
[/as]
To use this class, do as you normally would, but extend from the BasicForm class instead:

[as]
class LoadingScreen extends BasicForm {}
[/as]
screenshot of applying your form in Flash

  • 05 November 2006 01:33 PM
  •  
  •   Comments are closed.
  •   Log in or join for free to make a comment.

Page 1 of 3

  • of
  • 3
next last page
Topic actions
  •  Share on Facebook
  •  Share on Twitter
Topic Categories
  •  Show All Topics
  •  Development
    •  Server Side
    •  Client Side
  •  Creative Software
    •  Web
    •  Video
    •  3D
    •  Illustrator
    •  Photoshop Battles
    •  Photoshop
  •  Design
    •  Typography
    •  Resources & Insight
    •  Checkpoint
  •  Career
    •  Copyright Matters
    •  Advice & issues
    •  Job Seekers
    •  Job Offers
  •  Flash
    •  UltraMath
    •  OOP
    •  Third Party Tools
    •  Open Source alternatives
    •  Data Communication
    •  Components
    •  Flex
    •  AIR
    •  Flash Lite
    •  Flash Professional
    •  Flash Newbie
    •  ActionScript
    •  XML
  •  Lounge
    •  Polls
    •  Random Chat
    •  Showcase And Critique
    •  BombShock Award Nominations
  •  Community Essentials
    •  BombShock Award Winners
    •  Tutorials
    •  Interviews
    •  News
    •  Bitmap tutorials
Popular Topics
  • Sort by: 
  • Activity
  • Views
  • Comments
  • Likes
Advertise with us
  • Your advertisement here!
  • loading
Ultrashock
  • Creative Assets
  • Community
  • Blog
  1. Home
  2. Forum
+/-
Creative Assets
  • Categories
  • Contributors
  • How to buy
Make Money
  • Commission Rates
  • Referral Program
  • Contributor Program
Community
  • Activity Feed
  • Forum
  • Profiles
About
  • Quick Tour
  • Our History
  • Banners & Logos
Support
  • Contact Ultrashock
  • Advertise with us
  • Legal Information
  •  Keep up to date
  • Flash 775  Flash
  • Audio 6,481  Audio
  • Vector 2,130  Vectors
  • Image 12,338  Images
  • Creative Assets 21,724  Assets
  • Profiles 282,659  Members
  • Topics 93,762  Topics
  • Blog 4  Blog
  • Facebook 1,680  Facebook
  • Twitter 1,165  Twitter
  • Join our FREE monthly newsletter!
  • Archive
  • Invalid email address. Please try again.
Subscribe
  • ©2012 Ultrashock LLC - All rights reserved
  • Terms of Use
  • Privacy Policy
  • Switch to dark theme
  • RSS Feeds
  • Top

©2012 Ultrashock LLC - All rights reserved

Printed on Sat, February 04, 2012 - 19:37:41