Monthly Archives: March 2009

Flash Player Bug: Removing an event listener in another listener for the same type fails

Update: My bug report has been marked Not a Bug by Adobe. As Joeri mentions in this post’s comments, and Charles Liss explains in the bug report comments, Flash Player makes a copy of the event listeners internally when dispatchEvent() is called. It’s by design that a call to removeEventListener() will affect the original list of listeners, but it will not affect the copied list. I followed up with a request to describe this behavior in the API documentation so that others who run into the same weird behavior might have a better chance of learning why Flash Player seems to be behaving incorrectly.

I’ve been struggling off and on for days trying to figure out why a certain display object that I’d been fading in and out sometimes got stuck with partial visibility. Even when I explicitly set the alpha value to 0.0 or 1.0 after removing the animation and all its listeners, there was still the occasional situation where it would clearly receive a different value. I finally tracked down the following bug in Flash Player. If two functions are subscribed to the same event type from the same event dispatcher, and the first listener removes the second listener, the second listener is still called by Flash Player.

The following class demonstrates the problem.

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;

	public class EventErrorTest extends Sprite
	{
		public static var dispatcher:EventDispatcher = new EventDispatcher();

		public function EventErrorTest()
		{
			dispatcher.addEventListener(Event.COMPLETE, dispatcherComplete1Handler);
			dispatcher.addEventListener(Event.COMPLETE, dispatcherComplete2Handler);
			dispatcher.dispatchEvent(new Event(Event.COMPLETE));
			dispatcher.dispatchEvent(new Event(Event.COMPLETE));
		}

		private function dispatcherComplete1Handler(event:Event):void
		{
			dispatcher.removeEventListener(Event.COMPLETE, dispatcherComplete2Handler);
			trace("1");
		}

		private function dispatcherComplete2Handler(event:Event):void
		{
			trace("2");
		}
	}
}

The expected output is as follows:

1
1

Instead, my output console displays this instead:

1
2
1

Clearly, the second listener is still called the first time the event is dispatched. If you move the call to removeEventListener() to the line before the first call to dispatchEvent(), the output appears as expected.

I discovered this bug while using Grant Skinner’s excellent GTween library for AS3 in the current game I’ve developing. In my game, certain animations may be paused following the completion of other animations. Since (internally) all GTween instances listen to a static timing object, pausing a GTween inside an event listener attached to another GTween causes the supposedly-paused GTween to update the target’s properties one last time.

If you happen to be using GTween, and you encounter this same issue, adding the following line at the beginning of handleTick() in GTween.as should fix the problem:

if (_paused) return;

This event bug has been filed in Adobe’s public Flash Player database. You’re welcome to vote for it.

A preview of my first Flash game: Chroma Circuit

For the last couple of months, I’ve been quietly (or not so quietly, if you follow me on Twitter) developing a Flash game. Like a lot of software developers, games were what made me want to start programming in the first place. Finally, after getting a little burnt out and needing a bit of a break, I decided to spend some time focusing on making writing code fun for me again. After about a month and a half of exploration, I finished my first Flash game, and it’s called Chroma Circuit.

Screenshot of Chroma Circuit Title Screen Chroma Circuit’s Title Screen

The basic idea behind Chroma Circuit is that, in each level, you need to match up colors on neighboring elements. Generally, this is done by rotating them, but some other mechanics are introduced later on. The game works a lot like a jigsaw puzzle, in a way, if a bit faster paced. You need to align the colors for every element on-screen before you can advance to the next level. To rotate an element clockwise, you just click it with your mouse. Hold shift, and it will rotate in the other direction. Several of my testers independently called it “addicting”.

Screenshot of Chroma Circuit In Game 1 Three-Sided Rotating Elements

As the game progresses, levels contain more and more elements, and new elements are introduced over time. Three- and four-sided elements that may be rotated are the most basic types that appear when the game first starts. Later, transfer elements change colors and pass colors to different parts of the level to test the player’s spacial memory. Finally, in the last several levels, a new “bomb” element is introduced. Bombs must always match the colors of their neighboring elements, or they will explode, and you’ll be forced to restart the level.

Screenshot of Chroma Circuit In Game 2 Watch out for The Gauntlet!

The game contains 18 hand-crafted levels that I spent a lot of time tweaking and play-testing. I had so much fun putting it all together (especially the number of mathematical challenges required to draw the elements programmatically!), and I’m excited to get started on my next game. Chroma Circuit can now be played on my Bowler Hat Games company site, and at various distribution partners across the web. If you think it’s fun, please share it with your friends!

Open Source Flex Component: PopUpInitializer

At Adobe MAX this year, I got an idea for an interesting little Flex component. It took me a while to get around to implementing it, but I finally found some time. At the time, I had been building several quick prototype applications with floating information windows that needed to be added to the PopUpManager immediately when the application was initialized. Seeing as these were prototypes, I wanted to be able to do this rapidly without making new class files for each window, and if possible, I’d like to skip calling any methods on PopUpManager from a Script block. Basically, I wanted to throw as much as possible into one MXML file, and then have some component that’s smart enough to add my components to the PopUpManager. With those requirements in mind, the PopUpInitializer was born.

Here’s some example code that adds a TitleWindow to the PopUpManager using PopUpInitializer:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:toolbox="http://www.flextoolbox.com/2006/mxml">

    <toolbox:PopUpInitializer>
        <mx:TitleWindow title="An Example Pop-Up"
            x="50" y="50" width="200" height="200"/>
    </toolbox:PopUpInitializer>

</mx:Application>

It’s a simple class that implements IMXMLObject and makes liberal use of compiler metadata to make itself act like a regular UI container. For example, it uses the [DefaultProperty] metadata to pass the UIComponents to a controls property without having to specify that property name, and the [ArrayElementType] metadata to specify that the controls (there may be more than one) must all be of type mx.core.IUIComponent. Once it receives the list of controls, it waits for the application to be created, and then tosses them all up on the PopUpManager. A cleanup() method is added for convenience to remove all the controls from the PopUpManager, if desired.

Download the component SWC, an example, and the full source code from my Google Code repository. API documentation for PopUpInitializer is available as part of the common documentation with my other “Flex Toolbox” controls like ZoomFrame and PopUpThumbnail. As with most of my other open source code, PopUpInitializer is available under the terms of an MIT-style license.