boostworthyisryantaylor

Archive for December, 2007

Flash: Your Favorite Console Games Use It

I was catching up on my blog reading today and I noticed that Grant had an interesting post about how one of his team members had contributed Flash work to the game ‘Mass Effect’ for Xbox 360. Scrolling down through the comments, I realized that a lot of people were unaware that Flash is very prevalent in console game development pipelines these days.

I spent a year working at Electronic Arts - Tiburon as an interface designer/developer; the game menus and in-game HUDs are all Flash. Though I am rather limited on what I can say, they actually built their own version of Flash Player in-house for the game engine. There are a lot of limitations involved, but the big advantage is that they are able to hire web developers and leverage their existing skills to build the interface elements with minimal training. Prior to the next-gen consoles (Xbox 360, PS3, etc.), an in-house proprietary tool was used for interface development. Think of it as Flash without a timeline, and C instead of ActionScript. Using that thing is a friendly reminder of just how nice we have it with the Flash IDE.

So the next time you pick up a copy of Madden or one of the other EA Sports titles, you can smile knowing that all of those pretty menus and in-game HUDs are running on Flash Player.

1 comment

Cure For The ‘Unable to resolve asset for transcoding’ Compiler Error

Have you ever tried to embed an asset and ended up having mxmlc throw this error at you?

    Error: Unable to resolve 'yourAsset' for transcoding

I ran into this for the first time this evening. I was working on a Flex application and needed to embed a PNG file in one of my classes like so:

ActionScript:
  1. [Embed(source="../assets/images/myImage.png")]
  2. protected var myImage:Class;

No errors detected in the code, so I went ahead and did a debug build via Flex Builder and everything was just fine and dandy. Later on when I went to do a production build via my Ant build file, mxmlc threw that error. I quickly looked over my build file and everything looked fine, so I did a quick search online and didn't find any good solutions to this. Some others had posted about having this issue and resorted to adding their asset directory as a source directory. I wasn't down to do that, so I began experimenting. I finally managed to get it working; here is what did the trick:

ActionScript:
  1. [Embed(source="/../assets/images/myImage.png")]
  2. protected var myImage:Class;

Yep... Simply adding a slash in front of the '..' made all the difference in the world. Pretty incredible. I just thought I'd vent and share that since I know I'm not the only person out there that has been caught up on this.

35 comments

Ultrashock v2.0 Launched

It has been quite some time since I last visited Ultrashock.com, however I was pleased to hear that they finally launched the longly anticipated version 2.0 of their site today. I'm not sure if I prefer the new design over the old one, but I think the fact that they built their Flash elements on Flex is pretty cool. Head on over and check it out if you haven't already.

No comments

Let’s Talk About Data Binding

As a follow up to my previous post about Flex best practices, I wanted to go into more detail about data binding - as it is sort of a tough one to be consistent on. Now, I know I said before that binding via ActionScript is the way to go, but the simple fact is that there are definitely times in which binding in MXML makes more sense. For the sake of example, let's pretend we are building a modular task management application.

First off, we need a 'main' MXML document that contains a module loader for loading the various views our application will be constructed of.

CODE:
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <Main   xmlns="com.boostworthy.taskmanager.*"
  4.         xmlns:mx="http://www.adobe.com/2006/mxml"
  5.         layout="absolute"
  6.         width="100%"
  7.         height="100%"
  8. >
  9.    
  10.     <mx:Canvas x="0" y="50" width="100%" height="100%" id="viewContainer">
  11.         <mx:ModuleLoader id="viewModuleLoader" width="100%" height="100%" />
  12.     </mx:Canvas>
  13.    
  14. </Main>

Now, inside our 'Main' class, we will dynamically bind each view to our application data model upon being loaded. By binding via ActionScript (rather than MXML), we are able to avoid our application data model being a Singleton. There are a lot of reasons why this is good, but in a nut shell we are promoting loose-coupling. To make this process doable, we simply create an interface 'IView' which mandates that each of our views (modules) have a bindable getter/setter named 'dataProvider'. Inside our 'Main' class, we can then make the binding happen like so:

ActionScript:
  1. protected function onViewModuleLoad(event:ModuleEvent):void
  2. {
  3.     BindingUtils.bindProperty(viewModuleLoader.child, "dataProvider", applicationDataModel, "viewData");
  4. }

Now let's examine some situations in which binding via MXML makes sense. Inside our various views (modules), we'll have a bunch of components which make up that view. Let's pretend that one of our views lists out some various tasks coming up this week. To list out the tasks, let's use the 'Repeater' component.

CODE:
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <TaskViewerModule   xmlns="com.boostworthy.taskmanager.views.taskviewer.*"
  4.                     xmlns:components="components.taskviewer.*"
  5.                     xmlns:mx="http://www.adobe.com/2006/mxml"
  6.                     layout="absolute"
  7.                     width="100%"
  8.                     height="100%"
  9. >
  10.    
  11.     <mx:Script>
  12.         <![CDATA[
  13.             import com.boostworthy.taskmanager.data.taskviewer.TaskViewerModel;
  14.             import com.boostworthy.taskmanager.data.taskviewer.TaskViewerTaskModel;
  15.         ]]>
  16.     </mx:Script>
  17.    
  18.     <mx:Repeater    id="taskRepeater"
  19.                     dataProvider="{TaskViewerModel(dataProvider).tasks}"
  20.     >
  21.  
  22.             <components:TaskViewerTask  id="task"
  23.                                         dataProvider="{TaskViewerTaskModel(taskRepeater.currentItem)}"
  24.                                         x="0"
  25.                                         y="0"
  26.             />
  27.  
  28.     </mx:Repeater>
  29.    
  30. </TaskViewerModule>

To accomplish the same thing in ActionScript would require that we create 'UIComponentDescriptor' objects that contain information about any components being itemized by the 'Repeater'. It's certainly doable, but I feel like that definitely begins taking away from the ease of use and readability of the code. Perhaps a better solution is to keep the binding present in the MXML, but extract it out into separate 'Binding' tags so that it's not intertwined with the view itself.

CODE:
  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <TaskViewerModule   xmlns="com.boostworthy.taskmanager.views.taskviewer.*"
  4.                     xmlns:components="components.taskviewer.*"
  5.                     xmlns:mx="http://www.adobe.com/2006/mxml"
  6.                     layout="absolute"
  7.                     width="100%"
  8.                     height="100%"
  9. >
  10.    
  11.     <mx:Script>
  12.         <![CDATA[
  13.             import com.boostworthy.taskmanager.data.taskviewer.TaskViewerModel;
  14.             import com.boostworthy.taskmanager.data.taskviewer.TaskViewerTaskModel;
  15.         ]]>
  16.     </mx:Script>
  17.    
  18.     <mx:Repeater id="taskRepeater">
  19.         <components:TaskViewerTask  id="task" x="0" y="0" />
  20.     </mx:Repeater>
  21.    
  22.     <mx:Binding source="TaskViewerModel(dataProvider).tasks"           destination="taskRepeater.dataProvider" />
  23.     <mx:Binding source="TaskViewerTaskModel(taskRepeater.currentItem)" destination="task.dataProvider"         />
  24.    
  25. </TaskViewerModule>

I feel like this is a little cleaner and easier to read than inline binding, but you can definitely make arguments for either case.

On a final note, there is a page in the Flex 3 livedocs that discusses the differences between bindings in MXML and ActionScript. The most notable point is this:

The MXML compiler has better warning and error detection support than runtime data bindings defined by the bindProperty() or bindSetter() method.

Since MXML gets converted to ActionScript when compiled, it can detect errors at runtime that you cannot detect when binding using ActionScript. When you dig down into the 'BindingUtils' and 'ChangeWatcher' objects, you will see that this is due to the fact that you are passing properties as strings for the sake of being able to monitor property chains. Don't let this frighten you off from doing any binding in ActionScript, it's just something to be aware of.

So, as a rule of thumb, my recommendation is to use binding in ActionScript for dynamically loaded content (such as modules). Use binding in MXML when you are placing components directly inside of a view. This will make your life much easier when it comes time to do unit testing.

5 comments