Almer/Blank Labs

Hype/Papervision3D Demo

So after getting my hands on the new Hype framework, I wanted to put together a simple demo together that utilizes a combination of the SoundAnalyzer class and some 3D eye candy (via Papervision3D).

First off, I can say that I really like being able to play around with the sound spectrum using only a couple lines of code. I also used the Rythm class to run an enter frame method, which is very convenient in that I didn't need to manually set up an event and listener.

Lastly, I wanted to also utilize a tweening engine to smooth out the particle movement, but doing so cut the framerate by about 80% (a little better with TweenMax/TweenLite, but still not good enough). I also briefly played around with the Flint particle emitter, but I'm not familiar enough with Papervision/Flint to get it working how I wanted.

UPDATE - I decided to give a tween engine one more shot, and was able to use TweenMax while keeping the framerate at an acceptable level.

UPDATE 11/06/2009 - Updated code sample to reflect demo swf.

UPDATE 3/29/2010 - It's come to my attention that Wordpress tends to be a bit moody when it comes to code formatting in posts, especially in the case of vectors (which use the greater than/less than characters). That said, I've posted a couple pastebin examples:

Link --> Document class
Link --> ApplicationView class

...read more...

Organizing PureMVC Notifications

One of my favorite things about using PureMVC as my application framework are the standards established for organizing application code.  For notification names the common ways that I have seen these organized is by declaring constants on the concrete Facade, or by externalizing them to external classes.  I have tried both approaches, but my preferred method is to externalize the constants to notification classes.  Not only do I feel like its more organized because the notification names for a section of the application are centralized to different notification classes.  But, it is also a good way to clean up the amount of imports in the concrete Facade and centralize the Command registrations to these notification classes.

package com.project.controller.notifications
{
	import com.project.controller.commands.LoginCommand;
	import com.project.controller.commands.LogoutCommand;
 
	import org.puremvc.as3.interfaces.IFacade;
 
	public class LoginNotifications
	{
		static public const LOGIN:String = "LOGIN_NOTIFICATION";
 
		static public const LOGOUT:String = "LOGOUT_NOTIFICATION";
 
		public function LoginNotifications( facade:IFacade )
		{
			facade.registerCommand( LOGIN, LoginCommand );
			facade.registerCommand( LOGOUT, LogoutCommand );
		}
	}
}

Above is an example of a notification class. The constructor requires an IFacade object that it uses in the constructor to map notifications to commands using the IFacade object that is passed into the constructor. You can see how a bigger group of commands can be nicely organized into this class. Below is an example concrete Facade.

package com.project
{
	import com.project.controller.notifications.LoginNotifications;
 
	import org.puremvc.as3.patterns.facade.Facade;
 
	public class ProjectFacade extends Facade
	{
		public function ProjectFacade()
		{
			super();
		}
 
		static public function getInstance():ProjectFacade
		{
			if (!instance) instance = new ProjectFacade();
 
			return instance;
		}
 
		override protected function initializeController():void
		{
			super.initializeController();
 
			new LoginNotifications( this );
		}
	}
}

In the example above we can see the usage example for the notifications class for the login group. In the override for the initializeController() method, after initializing the controller, a LoginNotifications object is started with a reference to the IFacade instance that is the concrete facade, or simply "this". The amount of imports is reduced in the concrete facade, and there are less lines required in the initializeController() method, creating a neater, shorter concrete facade class.

This kind of organization is almost always based on personal preference, this just happens to be mine. =)

ActionScript 3 Display List Event Flow

Download the Flash CS3/AS3/FP9 Source Files for this post I've *finally* completed and posted a version of my ActionScript 3 Events workshop to the Rich Media Institute Online. I wrote the first full draft of this course almost a year ago, and I first taught it live in Los Angeles in May -- and now I've finally completed a version for online entitled, Unlocking ActionScript 3 Fluency: Events and the Broadcaster (see below for an extended excerpt of that course). I gave this name to the course because I believe (and argue in the course) that events really are the glue that bind everything together, and understanding events is vital to achieving fluency in ActionScript 3. Understanding how to reduce the potential for errors in your code makes you a better coder; understanding how to work with and around events makes you a fluent coder. Stated another way: everything in Flash is an object. There are two ways to make your objects communicate:
  1. Direct references: which even your grandmother knows not to use if possible, since direct references create less maintainable, less reusable, and more spaghetti-ish code.
  2. Events: which are dispatched and heard, and are like butter to work with
So, since objects need to communicate to do anything cool or complex, and since events are really the only clean way to have objects communicate (until you get into advanced stuff, like frameworks), well it looks like you need to understand events if you want to do anything fun, cool or sexy! Fortunately, events in AS3 are not that hard to work with -- in fact, they are incredibly consistent and pretty darn easy. They do have some pretty key limitations, but there are several ways around them, and my course teaches a CustomEvent and a CustomEvent Broadcaster as two such solutions. But before we get that far, there is one very most important aspect of working with events in ActionScript 3, a concept that many users of Flash do not understand when walking into my course. This concept of Display List Event Flow can be stated in two simple bullets. Events in Flash:
  • are objects
  • that can travel
Unlike in real life, where an 'event' is likely not tangible (try touching a party), events in Flash are as real and tangible as anything else, such as a MovieClip. Events have properties and methods, and they exist and occupy memory -- just like any other type of object. And these events have a lifespan -- they are born, they travel (or 'flow') and they die. Because Flash is an inherently visual platform, it is not surprising that the native event flow in Flash is inherently tied to the Display List -- the tree formed by the relationships of the display objects on our stage -- which can change each frame (since the MovieClip that's on my stage on this frame, might not be there on the next frame). To help you visualize what we're talking about when we say 'display list', here is a simple example display list: displayList Many events in AS3 (especially MouseEvents and KeyboardEvents, as well as any bubbling events of our own that we might dispatch in our movies) travel around the display list, in three phases:
  1. the capture phase: the event is heard down from the stage to the 'target' or source of the event
  2. the target phase: the event is heard on the target itself
  3. the bubbling phase: the event is heard back up the display list, from the target to the stage
So, looking back at our sample display list, let's say the user clicks on sub1a, whose full path is: stage.mc1.mc1_a.sub1a. In that case, the event (in our case, a MouseEvent) would be created and dispatched first on the stage, and then down to the target (or source, in our case, sub1a) of the event, in the capture phase. capture The event (again, in our case, a MouseEvent) is heard on the target (again, in our case, sub1a), in the target phase. target And finally, the event will be dispatched up the display list, from the target, to the stage, in the bubbling phase. bubble So, the full flow -- the complete lifespan of an event in the display list -- looks something like this: fullFlow So, to be clear, in this very, very simple example of the user clicking on sub1a, that MouseEvent can be heard in four separate locations, at seven separate occasions (3 in capture phase, 1 in target phase, and three again in the bubbles phase). Remember! The display list event flow not only tells us which parts of the display list will hear an event, but also which parts CAN NOT hear events (this limitation gets to why it can be so difficult, with the native AS3 event flow, to have different objects hear events from different parts of your movies). By default, when you write addEventListener in AS3, you will listen for events in the target and bubbles phases. If you use the 'useCapture' property of addEventListener, you can listen for events in the capture phase instead, as in:
addEventListener ( MouseEvent.CLICK , _onClick , true ) ;
Why would you ever want to hear an event in the capture phase? Well, honestly, it's rare, but we had to use it today at work to suppress keyboard input from being heard in parts of our movie in certain specific instances, so there are times when it can come in handy. But it's still useful to know about, because 'capture' makes 'bubbling' make a whole lot more sense! I've prepared two Flash CS3/AS3/FP9 samples (including source) that hopefully help demonstrate the concept. The first is intended to provide visual indication of the actual event flow, including the phases, and which branches of the display list can hear an event. The second provides a more accurate estimation of the timing of the event flow -- which lasts milliseconds -- by tracing messages to a textarea. I'm embedding the visual one at 50% so you can get a sense of it here. Visual Display List Event Flow Tracer Preview from R's AS3 Events Course Share and enjoy! -r

Moving rotated objects, the getBounds() bug, and how to fix it : Part One

Recently I was working on some bug fixes for a client project when I came across a bug with getBounds().  The issue that needed to be fixed had to do with an application that has an alignment feature.  Originally I had coded the alignment command to examine the x/y coordinates and the dimensions of the objects in order to figure out which coordinates to move the items.  This approach works correctly as long as the objects being aligned do not have any rotation set.

Throwing rotation into the mix no longer guarantees that the registration point is the top left coordinate of the item being aligned, which renders the first approach incorrect.  The first part of this blog post will go into the getBounds() method, what the bug is, and how to get the accurate bounds.

This SWF above demonstrates the issues with the getBounds() method.  On the stage is a MovieClip instance with a triangle shape in it, the MovieClip's rotation is set to 0 at start up.  Pressing the "Toggle MC Border" button draws a 1 pixel red line around the border of the MovieClip that has the triangle.  Pressing the "Toggle Unrotated getBounds()" displays the rectangle returned by the getBounds() method before the MovieClip has been rotated.  Before explaining the last two buttons, lets shift focus to the Rotation input at the top.  The first two buttons show the border and the unrotated bounds border.  The Rotation input lets us modify the rotation of the MovieClip.  If the object is rotated to 45 degrees by typing in 45 and clicking the "Set Rotation" button the first two buttons still perform the same function.  Except that now that the MovieClip is rotated the unrotated bounds rectangle now longer contains the shape inside of it.  If you turn off both the MC Border and the Unrotated getBounds(), and click on "Toggle Rotated getBounds()", you will see that the red border does not accurately draw to the expected size.  The top and right borders are further away from the right edge, which should meet at the top right of the shape.  If you click on "Toggle MC Border", you can visually see why.  The getBounds() method calculates the bounds Rectangle object by using the actual borders of the MovieClip, instead of actual graphical space that the MovieClip occupies.  If you now click on the fourth button, "Toggle getAccurateBounds()", you will see the blue rectangle drawn to the expected shape.  If the MovieClip's border is still on, the blue rectangle will be the same size as the red rectangle as seen in the screenshot below.

Screen shot 2009-11-02 at 6.32.32 PM

This is because the red 1 pixel border showing the MovieClip's border is taken into account, accurately, by the getAccurateBounds() method that I wrote.  That results in the bounds rectangle to do the same thing that getBounds() does.  If you press "Toggle MC Border" and turn off the MovieClip's border, and then turn the accurate border off and back on, you will see the difference in how the new actual bounds is actually wrapping the rotated triangle accurately.

Screen shot 2009-11-02 at 6.32.16 PM

Below is the _getAccurateBounds() method that is calculating the blue rectangle we see above.  This method demonstrates the technique to find the accurate bounds, but would likely need to be slightly altered to fit within real implementations depending on the actual architecture of the application its going to be used in because of the fact that it currently requires me to remove it from the stage to draw it independently of any other display objects.  It can probably also be accomplished by looping through the children of the clip's parent to turn off any visible items and turn them back on after the drawing process, but for the sake of simplicity in this example I will simply attach it to my placeholder bounds clip and then put it back.

Anyhow, the way that I accomplished this was by isolating the MovieClip that I want an accurate bounds Rectangle object from.  In my example I place it in a Sprite called boundsClip.  Next I set up a ColorTransform object with a color of blue (0×0000FF).  This ColorTransform object is used in the next step, where I create a BitmapData object sized to the clip's parent's dimensions, in this case the SWF's stage.  I then draw the boundsClip into the BitmapData object.  That is why I place the clip into a placeholder Sprite, so it can be drawn into the BitmapData in the correct position using its x,y coordinates.  In the draw() method, I use the colorTransform object to tint the bitmap blue.  This is crucial to the last step.  Before returning the accurate bounds, I place the clip back onto the stage.  And finally, I get the accurate bounds of the clip by using the getColorBoundsRect() method on the BitmapData object.  In the example application above I use this Rectangle object to accurately draw the blue rectangle, which shows the accurate bounds.

In my next post I will go into how to use the bounds rectangle to actually move the objects to a desired position.

You can download the FLA for the example application here: getBoundsBug.fla

function _getAccurateBounds( clip:Sprite ):Rectangle
{
	// Make a placeholder clip to draw the clip isolated from anything else
        // that is on stage.
        var boundsClip:Sprite = new Sprite();
            boundsClip.addChild( clip );
 
        // Make a ColorTransform object to tint the bitmap that is going to be
        // drawn based on the clip passed into _getAccurateBounds()
	var boundsColorTint:uint = 0x0000FF;
	var colorTransform:ColorTransform = new ColorTransform();
            colorTransform.color = boundsColorTint;
 
	// Draw a BitmapData object with the clip passed into _getAccurateBounds()
        // and tint the BitmapData to a color, I use blue.
        var bitmapData:BitmapData = new BitmapData( stage.stageWidth,
                                                    stage.stageHeight,
                                                    true,
                                                    0xFF000000 );
            bitmapData.draw( boundsClip, null, colorTransform );
 
        // Place the mc back onto the stage after drawing it.
        addChild( clip );
 
        // Return the Rectangle object from the getColorBoundsRect() method on
        // the BitmapData object.  This Rectangle object will contain the
        // correct bounds of the item you want the bounds of rotated or not.
        return bitmapData.getColorBoundsRect( 0xFFFFFF, boundsColorTint, false );
}

Flash CS4/AS3 SnapshotRectangle class

Source files for this posting>> Try me here! A few nights ago, as I was at my folks' house in New Jersey, and had a touch of the jet lag. So, checking Facebook, and one of my friends, Bram, had posted a challenge to his wall. He was looking for a Flash guy to create a Flash app to:
  • load any Flash video from your hard-drive
  • select the frame/location
  • drag-resize/reposition a marquee selection
  • save a JPG of the selected area to your hard-drive
I realized that this was possible in Flash Player 10 (no AIR required) because of the changes to the FileReference API (summarized by Lee Brimelow here), and that I actually already had all the code for it across several separate project files for courses I teach at the Rich Media Institute. The one limitation is that, with Flash video, you can only seek to keyframes (so, with this video snapshot tool, you can pause it at any time, but if you want to seek, you can only seek to keyframes), but Bram signed off on that proviso and so, in about two hours, I combined all the code snippets to make it work and got it to Bram before I went to bed. The next day, I realized it would actually be more useful if I encapsulated all of the code that handles the snapshot to a single, reusable class file / library symbol. So that's what I did. And I'm attaching the results here. Full disclaimer: This was just a goof and is not fool-proof code, but does demonstrate the concept nicely. So, what's included:
  • snapper.fla which includes the SnapshotRectangle MovieClip (on top of a sample image of my gorgeous golden, Lelia)
  • com.rblank.snapper.SnapshotRectangle.as, to which the SnapshotRectangle MovieClip symbol is linked, and which contains all of the custom code I've written for this sample
  • ActionScript 3 Core Libraries, created by the uber-scripters at Adobe, which I use here for JPEGEncoding (not inherent to the Flash Player 10 AS3 API). I'm including it in the download so it will work 'out-of-the-box' but you should of course download and use the most recent from their repository site
As you can see in the sample file (embedded and attached) the SnapshotRectangle has a:
  • Textfield instance, tf_dims, to display dimensions of the image that will be created
  • A MovieClip instance, named bg, that visually indicates the size of the image that will be created
  • A MovieClip instance, named nub, that will be used to resize the snapshot area
  • A NumericStepper instance, named ns_quality, that will be used to determine JPG quality
  • A Button instance, named btn_snap, that will be the trigger for saving the JPG
The code is fully commented, so check it out. But essentially, you:
  1. Create a BitmapData object and draw into it
  2. Encode the BitmapData into a ByteArray, using the JPGEncoder class
  3. Save the ByteArray (representing a JPG) to the user's computer, using the FileReference class
That's the pseudo-code. The actionscript is:
  1. //create a BitmapData instance, sized to match the width and height of the bg MovieClip instance
  2. _bitmapData =new BitmapData ( bg.width , bg.height );
  3. //draw the entire stage into the BitmapData instance, clipping by the _matrix
  4. _bitmapData.draw( stage );
  5. //create a new JPGEncoder instance (an AS3CoreLib class)
  6. //and pass in the current value of the ns_quality NumericStepper instance as the JPG quality
  7. _jpg= new JPGEncoder(ns_quality.value);
  8. //encode the _bitmapData into JPG data, stored in the _byteArray
  9. _byteArray=_jpg.encode(_bitmapData);
  10. //create the new FileReference instance through which to save the JPG data to the user's machine
  11. _fileRef_save = new FileReference ( );
  12. //save the _byteArray to the users computer, with a default name of 'RBlankSnapshot.jpg',
  13. //which the user will have a chance to rename before saving
  14. _fileRef_save.save( _byteArray , "RBlankSnapshot.jpg" );
You'll note that in the actual code, since this single MovieClip encapsulates all the drawing logic (meaning, it has no idea which specific display objects will actually be visible in the rendered image), so you have to hide this MovieClip while drawing into the bitmap data (otherwise, this SnapshotRectangle GUI will be in the JPG). Share and enjoy! -r Source files for this posting>>