I was drifting in and out of sleep, it being 520AM and as such was an appropriate time for such drifting, and I was dreaming of MovieClips and Events. I was thinking how MovieClips were kind of ungainly affairs, and like a lot of old Flash objects were of the dynamic nature...that is, they don't require explicit declaration of properties, and in the process of referencing a non-existant property you will bring it into being. This is the sort of behavior that makes debugging Flash somewhat trick, causing experienced programmers to roll their eyes at the laxness of the environment. But then it hit me: the technique I outlined earlier to re-establish object-context for a callback method was completely unnecessary...I could just store the object context right in the MovieClip itself! This would eliminate the hashing array and lookup!
In other words, something like this:
class ClipWrapper2
// Dave Seah's Magic Event Manager
static var ON_PRESS_EVENT = 10;
static var ON_RELEASE_EVENT = 11;
static function DispatchEvent (clip:MovieClip, eventType:Number) {
var execObj = lookup[clip];
var obj = clip.parentObj;
var method:Function = Function(obj.HandleClipEvent);
method.call(obj, eventType);
}
private var clip:MovieClip; // wrapped clip
function ClipWrapper2() {
clip = _root.createEmptyMovieClip();
clip.parentObj = this;
clip.onPress = function() {
ClipWrapper.DispatchEvent (this, ON_PRESS_EVENT)
}
clip.onRelease = function() {
ClipWrapper.DispatchEvent (this, ON_RELEASE_EVENT)
}
}
function HandleClipEvent(eventType:Number) {
switch (eventType) {
...
}
}
}
I don't know if this will work, but I woke up and had to write it down.
Although this insight may obselesce the old method, I still think it's pretty cool because it made use of the understanding of objects, hashes, addresses, references, and function contexts versus object contexts.
Back to sleep...
My buddy Jeff over at Scintus has been busy as always, but had time to point me towards Fresh Electronic Delivery. It's a design-oriented e-newsletter that serves up examples of great online design. It's similar in scope to portals like linked up and gecko9, but it feels more focused in the editorial sense. I like! Not to mention that the design is clean and lovely.
POSTED 10/10/2004 UNDER
Was just browsing my archives, and came across this image I made for my friend Barry's birthday party. Barry had just moved into his house and was consumed by painting. We thought it might be a good idea that he had something to distract him. Because we're evil.
This is a good example of some clip art scrounging + shameless use of built-in Photoshop layer effects. This follows some good advice from former CGD mentor Bill Colgrove, who taught me that clip art was not to be despised for its humble ready-to-wear origins, but to be used well.
The wax, unconvincing as it is, is all Photoshop effects, so it was easy to change the shape. The better way to do it would have been to render it in a 3D program that supported subsurface light scattering, but I am several versions behind on my 3DS Max license. Anyway, the result is a slightly cheesy rendering that reminds me of multimedia from the 90s, but Barry is also slightly cheesy :-)
I was curious what a 100K JPEG image would look like below the rather bland navigation bar. Not too bad, actually! The image whitespace at the top looks cool with the category tabs.
But yes, it's a big JPEG, both in terms of bandwidth and layout. The tick marks on the side are also a problem, because they blur out if the JPEG quality isn't high enough. And you can't really see very much text. Annoying? I guess I'll find out.
For a while, I've been wondering if there was a better way of catching events from MovieClips in an object-oriented context. If you use the "onEvent" hooks in MovieClip, they store only the address of your function. The way I did it in Prove It was by (taking deep breath) creating a static method in a special MovieClip wrapper class that used the this keyword as the key in a hashed array for looking up registered instance references...
In other words, something like this:
class ClipWrapper
// Dave Seah's Magic Event Manager
static var lookup:Array;
static var ON_PRESS_EVENT = 10;
static var ON_RELEASE_EVENT = 11;
static function RegisterClip(clip:MovieClip, obj, method:Function) {
var execObj = new Object();
execObj.obj = obj;
execObj.method = method;
lookup[clip]=execObj;
}
static function DispatchEvent (clip:MovieClip, eventType:Number) {
var execObj = lookup[clip];
var obj = execObj.obj;
var method = execObj.method;
method.call(obj, eventType);
}
private var clip:MovieClip; // wrapped clip
function ClipWrapper() {
clip = _root.createEmptyMovieClip();
RegisterClip(clip,this,HandleClipEvent);
clip.onPress = function () {
ClipWrapper.DispatchEvent (this, ON_PRESS_EVENT)
}
clip.onRelease = function () {
ClipWrapper.DispatchEvent (this, ON_RELEASE_EVENT)
}
}
function HandleClipEvent(eventType:Number) {
switch (eventType) {
...
}
}
}
This works around the problems with using the MovieClip event handlers onPressEvent or what have you...they do not execute in an object-context, so none of the instance variables are available. However, when the callback is executed, the anonymous function's this is set the movieclip that triggered the event. And since we have a static method defined as ClipWrapper.DispatchEvent(), we can call it so it can look up the object that has registered to receive events, then call the method & restore the object context.
I thought that was pretty cool, but registering and de-registering objects in the array is a bit slow when you get to 500 or so objects (the hashing slows way down). But in a ClipWrapper managing only a few clips, lookup should be relatively fast.
Other people must have figured this out, but I wasn't finding much online. So this seemed to indicate to me that there was a far easier way of doing it that I just was missing. After reading Essential ActionScript 2.0, I realized that this was the Mouse.AddListener function. You can track MouseUp, MouseDown, and MouseMove and roll-your-own event management this way. And Listeners are completely object friendly, unlike Callbacks.
There might still be an advantage to the way I was doing it before for making use of the built-in event masking that happens when you nest movieclips, so I'm continuing to look into it.
Extending a MovieClip directly might also get away from this problem, but I don't like writing code that requires you to establish class linkages in the Flash Library. A foible, I know.
For the current game project, I'm using Mouse.AddListener. The interactivity is pretty limited, so I don't anticipate having to roll things together. I'm curious what kind of benchmark improvement might occur by using a native code dispatch mechanism.
After using mod_rewrite to set up categories, I needed a visual way to distinguish them. Well, maybe I didn't need it, but I wanted it!
I split the top banner into two and made three sections that, using a bit of PHP, selects the correct navigation elements based on a new variable called $davecat. I adjusted the mod_rewrite rules in ht-access to append this variable when a url like `davidseah.com/work' is reached.
I modified wp-rss2.php to output $category_name as part of the blog title if a category feed was specified. So now when you choose an RSS feed for one of the three main categories, it will append the the category name so you know what you're getting.
Finally, I added paging by enabling the "posts paged" feature under Options->Reading, and adding the missing <?php posts_nav_link(); ?> just after The WordPress Loop.
It even seems to work with Staticize, which is nice. While I was at it, I moved the wordpress files into their own directory to clean up my webroot. My sis discovered it wasn't working for her though, so I had to manually delete the staticizecache directory, and that did the trick.
I feel good.
As the entries have been piling up here at davidseah.com, I've become aware of three main categories:
- Stuff I'm thinking about of an investigative nature
- Stuff that's interesting to my friends of a happy, fluffy nature
- Stuff that's related to work, media, and career in a more serious way
I looked at creating multiple blogs drawing from the same database tables in WordPress, but it seemed to be a hassle. Then I realized that mod_rewrite, which I'd used to set up the permalinks, could do this for me.
First of all, mod_rewrite is a part of the Apache web server that will take an incoming URL and "rewrite it" to something else. A simple example is to change an old URL to the newer, preferred one automatically.
But the cool thing is using it to change directory structures without moving them. And you can use it to convert dynamic pages with ugly http://davidseah.com/index.php?blah=10&foo='eggs' syntax into http://davidseah.com/eggs/10. Great for dynamic sites looking for some better search engine access, I'm told.
Anyway, to make a boring story less boring, I added three main categories to the site: the Davidocracy for news and information about me, the Think Tank for things I'm thinking about, and Working It for anything possibly related to making money and a livelihood. And, I've used mod_rewrite to add the following URLs:
So, if you're my sister and don't care about my work or thoughts, just bookmark http://davidseah.com/dave and you'll be all set. Likewise, if you're here to read my interests regarding new media, just bookmark the work one and never read another word about german welding goggles or my (adorable) cats again.
Most likely, no one is reading this and I've just wasted a bunch of time, but hey...got to plan for the future! I'll be adding separate RSS feeds and customized headers also. MOD_REWRITE + PHP is a good thing.
Today I registered to vote for the first time, heading down to the Nashua City Hall to stand in line. A couple of things struck me... the variety of people you see at City Hall, united in their common goal to have their vehicle registration renewed. I felt a small surge of civic duty as I stood in the City Clerk's Voter Registration Line. It was not unlike the way I felt when waiting to ride the Indiana Jones Adventure at Disneyland; the anticipation was more interesting than the actual experience, which was disappointingly free of drama. I had brought along a small wad of utility bills and other incontrovertible documents to vigorously assert my identity. But no, all they needed was my driver's license. They even printed out the form for me with everything filled in, and I just had to sign it. Absolutely painless...I give the experience an "B+". If I had gotten a free sticker, that might have pushed things into "A" territory.
My cousins Brian and Jason turned me on to Yakitate! Japan, a japanese comic book (manga) about bread making...Volume 11 has just been scanlated! You're all probably wondering, "bread making comics?" If you're even a nominal fan of the Iron Chef series on The Food Network, you might enjoy this manga. It's highly melodramatic, but filled with interesting (I assume) true tips about baking. Think "Rocky" meets "baking contests" and you're in the ballpark...just don't dwell on the Sylvester Stallone aspect too much.
The inset shows a piece of bread that has just been punched. "Well made bread has elasticity, and will bounce back!" Did I mention this manga totally rocks?
I spent yesterday outlining some of the basic classes for the interactive Flash game. With the amount of animation in this game, I think I will need a pretty robust event-driven graphics architecture. Also, I'd like to avoid the pain of asynchronous threading that I had in my last (and first) AS 2.0 app in Prove it.
I think I can combine both things into a common "Executor" class, which is an event-triggered serializing execution queue. Each Executor will have an ExecQueue with ExecObj's, which encapsulate object and method context. This is similar to the method I used in Prove It to create a synchronous XML loader, but more generalized. The rest of the architecture breaks the interaction into Game Logic, I/O Services, and Sprite Utilities. So here's how it's shaping up:
I/O Services
- ServerConnection
- ScreenMgr
- SoundMgr
- FileMgr
Sequencer
- Executor (base class or interface)
- ExecObj
- ExecQueue
Graphics
Entities
- Player(s)
- World
- Physics
- GM
Utilities
I may not worry so much about the executor objects right now, but the queue-based event triggering will be very important for developing a flexible interactive animation system. It's going to be a long week. :-)