|
by Brooke
Kantor, www.Kantors.org
I had been in the Flash periphery
for the past 3 years - I had originally purchased Flash 5 and upgraded
to MX, but had been unwilling to jump in wholeheartedly. I have a traditional
software development background. While familiar with Director, using the
Timeline for scripts was basically foreign to me. I had also experienced
the abuses in the use of Flash, and am a "Skip Intro" person
as well. When I saw a reference to Jonathan Kaye's and David Castillo's
book on Amazon, things clicked. 25 years ago I had worked with some behavioral
psychologists to build a software-based simulator to do train temps in
the use of word processors. Our methodology was sound, but the software
and hardware tools to build simulations were simply too prohibitive. We
generated some interest but no product. Shortly after, I slipped into
the IT mainstream.
The combination of Flash's animation capabilities and state networks,
combined with faster processors and better graphics, appeared to be the
missing ingredients that had eluded us back then. I was willing to put
it to the test. For a proof-of-concept I would use a simulation of a digital
camera. A number of friends had also suggested I try this. While digital
cameras adoption has become mainstream, documentation and training is
still quite analog.
What Versions to Use?
The first issue was what version of Flash, Actionscript, and consequently
the FlashSim state network to develop in. Flash MX 2004 had come out,
Actionscript 2.0 was being promoted by many Flash evangelists, but the
book was written for Flash MX, Actionscript 1.0, and Flash Player 6. I
decided to go with Actionscript 2.0 and Flash MX 2004, because I was already
familiar with Java and OOP, and this environment was more natural to me.
I also liked the FlashSim Actionscript 2.0 state network's centralized
event handling and the ability to pass events up the hierarchy. Jonathan
assured me that he would be migrating his architecture to AS 2.0 and would
support the process. Not only did this turn out to be true, but also what
I believe to be a critical success factor.
Designing My State Network
My first task
was to to build a statechart. As I owned a copy of Visio 2003, I wanted
to use its support for UML Statecharts. Not only is the terminology different
than what is used in the book, the Visio templates are also unwieldy to
use. After several hours of frustration I gave up and downloaded (and
eventually purchased) SmartDraw. SmartDraw subscribes to the KISS (keep-it-simple)
principle, and I now utilize the product for most of my diagram and modeling
tasks above and beyond statecharts.
After several false starts in state decomposition, I realized that I needed
to separate the physical from the purely logical essense of states. Similar
issues exist in data modeling vs. physical database design. In terms of
a camera, when you turn the camera over to view the top to turn the Jog
Dial from Off to Auto or another On setting, are you changing State or
merely changing orientation? At first, I recorded this as a State, but
quickly realized this was the "outside looking in" - not a true
behavioral state of the camera or event-response - simply perspective.
You can turn the jog dial without looking at it, similar to pressing the
shutter button, even though it is not facing you.
The next realization was that I was dealing with a hierarchy of states.
Some are unique to the Kodak 6330, while others are generic to digital
cameras. Essentially, whatever the canned pre-sets and modes the camera
vendor may provide, you are operating a digital camera in three ways -
(1) with the LCD off, using the ViewFinder; (2) with the LCD on; and (3)
using the LCD and buttons to change your camera settings. Given that understanding,
you can set of a basic hiearchy of states and sub-states, and event models
around these three super states. Every camera vendor will throw in some
curve balls, often because they don't consistently follow a standard design.
Translating the State Network to Flash
It was about the time I was ready to build my state network that Jonathan
came out with his XML
to code generator (for AS 2.0, it is included in the FStEng
AS 2.0 distribution). This is an excellent tool to get your state
network up-and-running so you can get down to business of linking everything
together. I went overboard with the notion of building a complete CASE
tool, starting with the Statechart, building a complete event-action table
in an XML Forms tool (Microsoft InfoPath) that would generate the XML
tool to feed Jonathan's XML to code generator. After a week of false starts,
I was able to partially deal with issues of recursion of hierarchical
states with states, and I was able to generate XML which would compile
under Jonathan's tool. But, the reality is, in terms of internal actions
and other event handling (and even some transitions), you cannot design
down to the lowest level of detail in a vacuum, before trying to work
with the code and your components to see if you really understand all
the behavior and interactivity your are attempting to simulate. The lesson
I learned was, design your states and transitions and build your shell
in XML (using Notepad if necessary), compile, and get the State Network
up-and-running. Then, you'll be able to add your Actionscript code at
the right spot, and test and debug from there.
Building a Simulation in Phases
|
Statechart
for Sim Version 1
(click to open as PDF) |
|
Statechart
for Sim Version 2
(click to open as PDF) |
It's easy to want to bite off
more than you can chew. Given this was a proof of concept, I did not want
to spend months attempting to build an elaborate simulation of the camera's
entire functionality, only to discover I had taken a wrong path at the
beginning, and I would then be stuck undoing months of essentially useless
design and code. I needed something functional that could be put to the
test in a month's timeframe. So, I identified the core functionality around
turning the camera on and taking a picture, and deferred some of the more
mundane but tedious tasks (such as Picture Review and changing camera
settings via menus in the LCD) to Phase II.
For the Model Layer, instead of utilizing another state network, I utilized
a camera object (i.e. an instantiation of a custom Camera class) with
getters and setters for persistence. I could both query the model layer
and utilize dynamic references to Movie Clips in Control Layer functions
this way.
The process of building out my simulation from the state network and AS2
components was smooth. Surprisingly, the feature that was most difficult
to simulate was the Delete Picture menu in the camera LCD. As menu options
are navigated and selected by the use of arrow buttons on the camera,
I needed to block the use of the mouse for navigation and selection. I
also wanted to simulate the look-and-feel of these menus in the camera
LCD. Using a Flash List Component was the most obvious basis for simulation,
but there were complications. The Flash MX UI Listbox component for AS1
was changed to the Flash UI List component for AS2. Moreover, Macromedia
provided a set of Flash MX UI components for AS2 users comfortable using
the MX components. As confusing as this sounds, the Help documentation
is even more confusing. Through much trial-and-error, I discovered that
the ONLY method that seems to work with the look-and-feel of the Flash
UI List component is setStyle, which utilizes name-value pairs. After
getting my List Component's look-and-feel to match the camera's Delete
Picture menu, I wanted to capture these settings in a stylesheet, as I
knew I would be simulating similar menus throughout the simulation. Again,
the documentation (and a number of 3rd party books) steered me down the
wrong path. Again, it was another variation of the setStyle method that
finally saved the day. I bottled up my List look-and-feel parameters as
properties in a listStyle object, created by the following statement:
var
listStyle = _global.styles.newStyle = new mx.styles.CSSStyleDeclaration();
I then could associate my
List component to this stylesheet through the following statement:
<component path
& name>.setStyle("styleName", listStyle);
The Presentation
Upon finishing Version 1 of the digital camera simulation, it was quite
apparent that a non-digital camera savvy person would not have a clue
how to use the simulation. A Presentation Layer was needed. I did not
want to provide static text instructions (i.e. a manual), and I wanted
to give users a chance to explore on their own. What made the most sense
was to provide some minimal text that explained the current camera state
and most likely functions to undertake next, along with the option to
see demonstrations of these functions. For demonstration purposes, I wanted
to utililize context-sensitive screencams on demand (i.e. available when
the user wants to view it) over the web - in other words a webcam on demand.
Macromedia's RoboDemo was out of my budget, but I discovered that Qarbon's
more affordable ViewletCam tool generates its final output as a SWF. So,
I literally took movies of me demonstrating some functionality (e.g. setting
the shutter) in my simulation. I then annotated them in the ViewletCam
tool and generated SWFs. I then provided "Demo This" buttonAttach
components in my simulation alongside "What Can You Do Next"
text. These buttons generate events captured by the central event handler,
which in turn are captured by internal actions in my state network, which
in turn load the appropriate SWF at the appropriate time.
Version 2
In Version 2 of the camera simulation I added the ability to change camera
subjects (12 subjects x 3 zoom settings), along with a "Review Picture"
mode. After taking a few photos, you can review them by clicking on the
Review button. In Review mode you can scroll through your shots like a
slide show, enlarge (2x and 4x) and scroll/pan through them in the LCD,
see all of your shots as thumbnails, and delete pictures selectively or
entirely.
I record a user's "camera shots" in a Pictures array in my Camera
object ( the Model Layer). I dynamically display thumbnails of these saved
pictures in 3 x 3 grids within the LCD. None of the Actionscript to generate
this functionality, along with enlargments and delete states, was overly
difficult, and adding additional states, transitions, and internal actions
was pretty methodical. Preparing and re-sizing the photo assets for this
phase was time consuming, but I had a pretty good workflow established
in Fireworks. I imported all "regular sized" pictures and thumbnails
into my working .fla file as lossless .png files and converted to movie
clips. The 2x and 4x enlargements would have created an excessively large
.swf file, so these are loaded externally, using the movieClip loadMovie
method and a pre-loader. For the Delete Pictures menu, I had to create
a transparent version of my Actionscript v2 List component, and thus needed
another stylesheet. Modifying stylesheets for components is a maddening
process, because you need to track down what property of which layer of
the inheritance model needs to be manipulated, and upon finding that,
the correct attribute value to use. According to the Flash MX 2004 documentation,
the default background of the List component is transparent. However,
it is indeed white. I attempted to change it and its ScrollSelectList
ancestor to "none", 0x010101, "transparent", and about
anything else Macromedia suggested or I could think of. Finally, I resorted
to Google and discovered a number of other users had reported the same
problem. Somebody in the UK suggested "null", and that finally
worked.
What's Next
Most of the camera functionality that hasn't been simulated involves changing
menu settings in the LCD. As I've already simulated LCD menus in the various
"Delete Picture" modes, this should not be difficult, but possibly
time consuming, as I would have to come up with additional stylesheets
and again deal with class inheritance with stylesheet hell. While achievable,
I question the value of simulating the camera settings menus, as these
are fairly straghtforward to use to begin with. Many have suggested that
I get into ways of taking better pictures and monitoring user performance.
Right now, the camera simulation is still a little to simple for that.
About the only worthwhile thing to monitor is that the user actually put
the lens in auto focus before shooting a picture. If I can add red-eye
and a few other "good digital photography" features, this may
be worthwhile. Now that I understand the FStEng 1.5 APIs better, I may
drill down into this.
I will probably add voice narratives to my web-cams. These are produced
in Qarbon, which generates SWF output. Initial testing seems to indicate
that voice narratives will add about 100K to a 1-megabyte movie. However,
I don't think a user can read the cartoon explanation and watch the camera
component movements at the same time. |
| This
month's download is
our Flash MX 2004 joystick component, FMXISJoystick,
from our component set. Check out the way we skin it and other components
using Linkage ID's, as well as features such as the listener property,
and easy event name changing to avoid multiple instance conflict.
Sign
up now and get access to download the code through the subscriber's
edition! |
To find out more about
the components and skins, CLICK
HERE
My experiences with Macromedia's
new (v2) component architecture in general have been very favorable. I
was glad to see several structural improvements regarding standardization
and extensibility (with the new UIComponent
base class).
In terms of learning to develop
new components, I feel the learning curve for creating real components
has increased, but I found articles at Ultrashock,
particularly one by Chafic Kazoun, were very helpful in making the transition
from AS 1 to AS 2. I started with Joey
Lott's article, which is excellent, and then transitioned to Chafic's
and others on Ultrashock and the Flash
DevNet Center. Chafic points out some subtleties that others have
not point out, such as mergedClipParameters. Macromedia has done a much
better job of documentation for the new components, actually releasing
the components with good articles, such as one by Andreas
Heim. There are still, however, lots of intermediate and advanced
topics that need good descriptions (I guess that is always the case!).
I say it in jest, but I am
still somewhat afraid of the skinning models, though the CSS-like architecture
certainly makes sense. For my components, shown below, I preferred a simple
alternative: add properties for each main graphic element which designers
can change by assigning a linkage ID. For example, to change the graphics
for a knob, one just creates a new Movie Clip, assigns a linkage ID, then
types in the linkage ID into the property of the knob component.
I was happy to see that Macromedia
changed the event mechanism to a listener model (in our book, I told you
so!) rather than the callback system of their v1 architecture. Colin Moock
recently published a
chapter from his ActionScript 2.0 book about this. I used this new
architecture for my components, but added a few more features, among them
are:
- The ability to change the
name of the events. In Macromedia's v2 architecture, if you have two
buttons on the stage with one listener following both, both components
send the "click" event and the listener has to distinguish
the buttons based on the instance. I thought it would be better to allow
users to change the event name, since while the act of clicking is the
same, the meaning of the event is different (coming from different buttons).
- I like to set the first
listener in the property panel for the component, rather than initializing
it programmatically. Therefore, I needed to add a mechanism in which
you can specify the listener by name, rather than by reference. To be
complete, I also allow the name to include absolute and relative prefixes,
such as _parent, _level, _global, etc.
- I wanted a shorthand way
for a listener to subscribe to all events for a given component, not
on an event-by-event basis. I therefore added a method called addListener
(instead of addEventListener).
- Perhaps the biggest difference
with the v2 components I made is that I distribute them as FLA's rather
than compiled clips. I did this for two reasons:
- Compiled clips are better
because they are self-contained--for FLA components, when you give
someone else your FLA you have to give them the FLA and AS file
of the components as well--however, they also suffer from some drawbacks.
First, if you use Live Preview with a compiled clip, then all instances
of the component will have the same live preview. This means if
you have two different digital displays on the stage and you set
the properties of one, it will show up on both. Why even use Live
Preview with compiled clips, you ask, now that compiled clips show
their ultimate appearance during authoring? The answer is that they
really don't work that way in all cases, especially the cases I
need. For my jog, potentiometer, and joystick components, I made
the center point of the graphics at the local coordinates of 0,0.
It's slightly easier to do the math when it is centered at 0,0.
Well the bounding box of a compiled clip assumes its 0,0 point is
in the upper left corner, and masks the rest of the graphics during
authoring in the Flash IDE. When you publish the movie, Flash does
not have this restriction, so it draws the component fine.
- The second reason I
published them as FLA's is so that one can easily change the graphics
for all stage instances by modifying the clips in the Library. I
just don't think the v2 skinning architecture is mature enough to
make bypassing this convenience obsolete. I understand the advantages
of compiled clips for commercial component developers, but I have
always loved the ability to change graphics by modifying the Library
elements. With the new components, this is much more difficult (you
have to get the FLA version of the components from the Flash install
directory).
If you want to preview the
functionality of the set, you can see the documentation online by CLICKING
HERE.
As a result of this architecture,
I am starting a project to collect and sell component skins. You can see
the beginning of this effort at http://www.FlashSim.com/FMXISComponents/Skins.
The idea is that designers create skins for the various components, and
then split money received from sales of the skins with us. As an added
incentive, designers who submit skins will get the respective component(s)
for free. Also, in a few weeks, I will be starting an affiliate
program so that web site who refer purchasers can also make money.
If there are components you
don't see but want, email me, or post a message on the component
discussion board, and I or someone else may build it for you (well,
not just you, but you get the point)! |