Filed under AS3

Snippet Saturday: quick random choice

by

Today’s Snippet Saturday (actually, Sunday) is a quick shortcut for choosing one of several strings, objects, etc. randomly.

Now, I wouldn’t really recommend using this code in a project. There are ways to do the same thing that are much more readable and less error prone. Instead, I thought it was an interesting experiment to show off some of how AS3′s syntax works for those of you who may not have seen something like this.

What’s happening here? Let’s break it down.

  • ["Alpha", "Bravo", "Charlie"] – Here we are instantiating a new array and populating it with three strings. This is essentially the same as:
    var a:Array = new Array();
    a[0] = "Alpha";
    a[1] = "Bravo";
    a[2] = "Charlie";
    
  • [...] – next is another pair of square brackets. This is an array access operator. In other words, everything between the two brackets will be evaluated as the index of the array to retrieve.
  • int(...) – This is an explicit type-cast to an int. That means that everything inside those parentheses is evaluated and flash attempts to convert from whatever data type it is to an integer. In the case of decimal numbers, they are rounded down so this is similar to using Math.floor().
  • Math.random() * 3 – random() of course produces a random floating point (decimal) number between 0.0 and (almost but not quite) 1.0. Multiplying that number by 3 (the length of the array) produces a number between 0.0 and 3.0 (technically, between 0 and 2.99999999etc).

The result, an array is created with three strings, a random number between 0.0 and (almost) 3.0 is generated, it is rounded down to an int between 0 and 2, that number is used as the index of the array to look up. The result will be randomly one of the three strings.

I hope you found this interesting!

Tagged ,

Snippet Saturday: isRoughlyEqual() PLUS: as3-utils

by

Last week, I started a (hopefully) weekly post where I throw out a (hopefully) useful piece of code for people to (hopefully) use in their projects. I’m calling this #SnippetSaturday.

John Lindquist commented almost immediately that there is a project on github designed to collect these sorts of useful little snippets of code. It’s called as3-utils. Check it out!

This week’s snippet, isRoughlyEqual(), provides a simple way to find out if two numbers are in the ballpark of each other.

I’ve added it to the as3-utils project too.
http://github.com/mimshwright/as3-utils/blob/master/src/utils/number/isRoughlyEqual.as

Tagged , ,

Snippet Saturday: limit() function

by

So I’m sitting on a bunch of pretty useful code and I’m not sure how to share it with people. I could create a massive library that combines all the miscellaneous bits into a single, poorly documented library, but after looking at the Flash Game Dojo’s wiki, I’m starting to believe more strongly in the idea of releasing code in smaller pieces that achieve a particular function. So, I’m going to try to kick off this idea of #SnippetSaturday. I’m sure I won’t manage to post something every week but I’ll do my best. If you’ve got a blog or just twitter, I’d encourage you to join in too!

Anyway, here’s my first contribution. It’s a simple little function that limits a number between an upper and lower limit.

BTW, I used gist.github.com for this but snipplr is good too. If you know of others, leave a comment!

Tagged , , ,

Matryoshka Functions

by


The other day, I was working with the Flex function BindingUtil.bindProperty(). I always have a hard time remembering which pair of arguments comes first, the ‘site’ or the ‘host’ and to be honest, the names don’t really make much sense to me. “Oh, if only this were an Objective-C project I would have to laboriously type out each name of each parameter.” I thought, “It would be so much more obvious if it were writen like Bind.property("foo").fromObject(bar).toTheValueOfProperty("foo").ofObject(baz);.”

What followed was the discovery/invention of just such a thing, a nested, super-verbose function. The function achieves this by returning an instance of an internal class with nothing in it except for the next step in the chain.

package
{
	public class Bind
	{
		public static function updateProperty(object:Object, property:String):BindSource {
			return new BindSource(object, property);
		}
	}
}
import mx.binding.utils.BindingUtils;
class BindSource {

	private var targetObject:Object;
	private var targetProperty:String;

	public function BindSource(targetObject:Object, targetProperty:String):void {
		this.targetObject = targetObject;
		this.targetProperty = targetProperty;
	} 

	public function whenSourcePropertyChanges(object:Object, property:String):void {
		BindingUtils.bindProperty(targetObject, targetProperty, object, property);
	}
}

To call this function you would use:

Bind.updateProperty(foo, "bar").whenSourcePropertyChanges(baz, "bar");

Kinda cool! I soon realized that this technique has some characteristics that Objective-C messages don’t have. For example, each step can use more than one parameter (plus they each get their own code hinting). You can also provide multiple choices for what to do next providing a sort of branching behavior.

AngleFinder.getAngleOfVector(4, 4).inDegrees() 	// 45°
AngleFinder.getAngleOfVector(4, 4).inRadians() 	// π/4

You can even do free-form stacking of functions like this.

new Calculator	(5)                    // 5
                        .plus(3)            // 8
                        .times(2)          // 16
                        .dividedBy(4)   // 4
                        .minus(1)         // 3
                        .plus(2)            // 5
                        .equals();

I proudly named these “Matryoshka Functions” after the Russian stacking dolls even though I’m sure I’m not the first to try something like this. As it turns out, they’re about 10% practical and 90% clever hack. Even though there could be some potential use for this (especially with complicated, repetitive tasks), this technique conflicts too much with the way we normally code in ActionScript. Still, I thought it was cool enough to share with everyone.

Pros:

  • Very descriptive
  • Branching and stacking effect is interesting and potentially useful
  • Code hinting shows the next step in the function as well as the parameter names
  • Looks cool!

Cons:

  • Abominable code style. Too weird to be useful.
  • Difficult to know when to stop calling functions
  • Not completing the function will produce unexpected results with no compile-time errors
  • Each step requires you to pass the parameters from the previous step

Can you find any use of these? Can you think of a more efficient way to write the functions? Any other thoughts?

Check out the source with multiple examples (FlashBuilder project).
MatroshkaFunctionDemo

Killing 3D Transforms

by

Here’s a quick tip. If you’ve ever dealt with 3D in Flash Player 10+ you’ll know that DisplayObjects in 3D in Flash Player are bitmap-cached; only the bitmap representation is transformed in 3D. Recently I was working on a site where objects landed on the stage, but after landing, they appeared really muddy, which was obvious when you looked at the text they contained. Even though they were completely flat, they were still using bitmap proxies! Not great.

Turning a DisplayObject into a 3D DisplayObject is as simple as assigning a value to its rotationX, rotationY, rotationZ, or z properties. But how do you turn it back? I tried giving all these properties a value of 0, but after their animations completed they were already 0. An object at z=0 still renders in 3D, using bitmap caching. Setting these values to NaN was no better.

The solution I found is to null out the 3D transformation matrix and assign a 2D transformation matrix. This can be accomplished like so for a DisplayObject named sprite:

var matrix:Matrix = new Matrix();
matrix.translate(sprite.x, sprite.y);
matrix.rotate(sprite.rotationZ);
sprite.transform.matrix3D = null;
sprite.transform.matrix = matrix;

In this code I simply drop the transformations that are inapplicable to 2D space. This is fine when your object is already coplanar with the stage.

Anyway, quick tip if this ever had you scratching your head too.