Undocumented ActionScript isn't the only fertile hunting ground for the curious coder. Discover nonobvious uses for several obscure ActionScript operators.

Although ActionScript is large, typical developers can solve 90% of their problems using 10% of the available features. The remaining ActionScript is used only rarely or for very specific purposes. Some ActionScript is used rarely because developers don't know how to use it or it has a nonobvious use.

Here are a few alternative uses for obscure ActionScript commands and operators.

The modulo operator, `%`,
returns the remainder of a division operation assuming no decimal
part. For example, the result of 15 modulo 6 is 3, which is the
remainder of 15 divided by 6:

trace(15 % 6); // Displays: 3

What is it good for? Because the result of `a%b` can
never be greater than `b`, you can use modulo
division to limit (*clamp* or
*clip*) an expression `a` to the
range 0 to `b`.

The following animation helps visualize the results. If you attach
the following code to the first frame of a new movie, you will see
that the center point of the `ball` movie clip never
goes beyond the line at `x = 300`. The
*clamp( )* function, which acts as the
*onEnterFrame( )* handler for the
`ball` clip, uses `(this._x +
speed)%300` to set the position of the ball. This limits
`ball._x` to the range 0 to 300.

function clamp( ):Void { this._x = (this._x + speed)%300; } // Createvar ball:MovieClip = this.createEmptyMovieClip("ball", this.getNextHighestDepth( )); ball.lineStyle(20, 0x0, 100); ball.lineTo(0, 1); ball._x = 0; ball._y = 200; // Create line this.lineStyle(null, 0x0, 100); this.moveTo(300, 190); this.lineTo(300, 210); var speed = 4; // Set up animation ball.onEnterFrame = clamp;ball

Another use of modulo is in snapping a value to a particular multiple
of a number. If `x = a%b`, you can constrain
`x` to whole values that are divisible by
`b` by either adding or subtracting
`x%b` from `x`. These lines display
300 and 400:

x = 350; trace(x - x%100); // Next closest lower number divisible by 100 trace(x + x%100); // Next closest higher number divisible by 100

The following code uses snapping in a simple drag-and-drop example.
The `ball` movie clip follows the mouse, snapping to
the nearest 30-pixel multiple.

ball.onMouseMove = function( ) { this._x = _xmouse - _xmouse%size; this._y = _ymouse - _ymouse%size; updateAfterEvent( ); }; size = 30;

The dragger.fla file on this book's web site uses the snapping code to create a series of tiles that can be arranged only along a grid. If you run the example and drag and drop the colored squares, you will see that they snap to the nearest whole position, allowing you to stack them edge to edge, as seen on the right side of Figure 10-10.

This sort of feature would be useful in:

Flash puzzle games, especially sliding block games and jigsaws

Flash tile-based action games (platform games)

Flash board games

Icon-driven Flash OS-type interfaces (in which you create a site that looks like an operating system desktop, typically driven by point, click, and drag-and-drop icons)

The *Math.abs(
)* method returns an
expression's absolute value.
`Math.abs(5)` and `Math.abs(-5)`
both return 5. Not the most exciting method, but it is an efficient
way to limit a number at both ends of a scale. Simply offset the
scale so that the top and bottom ends of the scale are the same
absolute number (such as -5 and +5 instead of 0 and 10).

Checking the upper and lower limits for the x and y coordinates of a clip traditionally requires four conditionals. You can hack this down to two conditionals by moving the origin to the center of the Stage. In the case of a default Stage size (550 400), the leftmost and rightmost x positions are -275 and 275 (instead of 0 and 550) and the topmost and bottommost y positions are -200 and 200 (instead of 0 and 400).

This optimization isn't apparent unless you need
things to run really fast, as in the following
code. It uses *setInterval( )* with a
one-millisecond interval to force Flash to run the animation as fast
as it can. The optimized range-checking functions are shown in bold.

function anim(target:MovieClip):Void { if (Math.abs(target._x) > 275) { target.xSpeed = -target.xSpeed; } if (Math.abs(target._y) > 200) { target.ySpeed = -target.ySpeed; } target._x += target.xSpeed; target._y += target.ySpeed; updateAfterEvent( ); } // Create balls for (var i = 0; i < 20; i++) { var ball:MovieClip = this.createEmptyMovieClip("ball"+i, this.getNextHighestDepth( )); ball.lineStyle(5, 0x0808AF, 100); ball.lineTo(0, 1); ball.xSpeed = Math.random( ) * 10; ball.ySpeed = Math.random( ) * 10; this["fastAnim"+i] = setInterval(anim, 1, ball); } // Capture screen extents var temp:String = Stage.scaleMode; Stage.scaleMode = "exactFit"; var sWidth:Number = Stage.width; var sHeight:Number = Stage.height; Stage.scaleMode = temp; // Move Stage's original origin to center this._x = sWidth / 2; this._y = sHeight / 2; // Mark out Stage this.lineStyle(undefined, 0x0, 100); this.beginFill(0xF0FAFF, 100); this.moveTo(-sWidth, sHeight), this.lineTo(sWidth, sHeight); this.lineTo(sWidth, -sHeight), this.lineTo(-sWidth, -sHeight); this.endFill( );

The still image of the output shown in Figure 10-11 doesn't do the effect justice. On a modern computer, the dots fly quickly around the Stage. If you do not have a high enough monitor refresh rate, you will not see many of the dots at all, but rather the trails they leave behind!

On my machine, I see around 15% to 20% faster animation using optimized range checking with 5-pixel wide circular movie clips. The speed increase depends heavily on the speed of your computer and the complexity of the movie clip graphics (remembering that screen redraw, not the code, is usually the performance bottleneck).

The following code uses the *Math.min(
)* and *Math.max( )*
methods to "clip" a value to a
particular range. It skips the conditional expression and simply
forces the value into the desired range. (The code assumes you
haven't shifted the origin as in the previous
example.) It works well when you want to restrict an
object's range of motion, say a puck along a slider,
but not for objects that need to "reverse
course," such as a bouncing ball. Here, the
calculation prevents the movie clip from traveling off stage:

function anim(target:MovieClip):Void { target._x = Math.max (0, Math.min (target._x + target.xSpeed, 550)); target._y = Math.max (0, Math.min (target._y + target.ySpeed, 400)); updateAfterEvent( ); }

Or, more generally:

function clip(input:Number, minVal:Number, maxVal:Number):Number { return Math.max (minVal, Math.min (input, maxVal)); } function anim(target:MovieClip):Void { target._x = clip(target._x + target.xSpeed, 0, 550); target._y = clip(target._y + target.ySpeed, 0, 400); updateAfterEvent( ); }

Flash's base unit of measure is a twentieth of a point (a "twip"). Flash allows you to define pixel values with precision down to .05 pixels (smaller increments are ignored), so drawing a pixel at the point (10.5, 10.5) is legal. Flash displays graphics at fractional locations using antialiasing. By blurring the pixel, Flash attempts to give the impression that the pixel is at the fractional position, even though the video card can address pixels only at integer positions, such as (10, 10). The problem is that you can lose detail through the blurring effect, so it is best to position graphics at whole-pixel intervals.

Inertial motion [Hack #39] is one
of the most oft-used tricks in Flash. However, the standard inertia
algorithm returns fractional pixel values. For example, the following
code creates the ubiquitous `ball` movie clip and
animates it with an inertial motion toward the mouse position (a.k.a.
the Cheesy Flash Mouse Follower effect):

inertia = function ( ):Void { this._x -= (this._x - _xmouse) / 4; this._y -= (this._y - _ymouse) / 4; trace(this._x) }; // Createvar ball:MovieClip = this.createEmptyMovieClip("ball", this.getNextHighestDepth( )); ball.lineStyle(20, 0x0, 100); ball.lineTo(0, 1); ball.onEnterFrame = inertia;ball

Almost none of the traced values (`this._x`) give an
integer, which means that the clip can appear blurry because it is
positioned on the Stage between physical pixel positions. More
typically, if you are adding inertia effects to drop-down menus or
scrollbars, it will make any associated text fuzzy and wreak havoc
with pixel fonts.

Instead of dividing by 4 in the preceding example (which, incidentally, is an arbitrary value, chosen because it gives a pleasing inertial effect at my chosen frame rate of 18 fps), you can instead bit-shift the value to the right by 2 binary digits via the following:

inertia = function ( ):Void { this._x -= (this._x - _xmouse) >> 2; this._y -= (this._y - _ymouse) >> 2; trace(this._x) };

The `>>` `2` operation tells
Flash to shift the bits in the answer 2 positions to the right,
effectively dividing the result by 2^{2}, or
4, using integer division. This is faster than the standard
ActionScript division operator, /, which performs floating-point
division. Now the *trace( )* statement displays
integer values only, which keeps your animated content much sharper,
assuming that the content is snapped to the nearest pixel
(ViewSnappingSnap to Pixels) and all your
graphics are rendered in exact pixel sizes (you can ensure this by
specifying integer values for Width and Height in the Properties
panel).

As you can see, there are many ways to use the more obscure features of ActionScript, which are often more optimized or shorter than mainstream solutions. It pays to keep an eye out for alternative ActionScript when performance is at a premium.