Tribe Called Guest

May 5th, 2013

part of a tribe called guest
unless we hit the reset, reflect
disconnection from what we know is true
perpetually blue
no bees, no birds, no snakes, no fools

waiting for a change
increasing pain, blame, meaningless frames
take a collective breathe, sigh out loud
our tribe’s not on a cloud
it’s in our hearts, homes,
and starring people that make us proud

part of a tribe called guest
entering peoples’ homes when their souls are alone
we buy expensive frills,
for ego fills and captivated by meaningless thrills
this path’s been paved before
the eventual cracks remind us what it’s really for

Century Romance

July 13th, 2012

structure lines,
foundation of function,
and the unromantic nature of port 80
connection is logical not spiritual
attempts to super-impose spirit on
the wires and routers of love and friendship
godly white sheets blanket a pile of trash
downloading reality television
over the desire to party without a playlist
a generation of armchair groupies
chemically enhanced , torrent-wielding criminals
bound to the logic of choice and freedom
selfish prescriptions of selfless self-sacrifice

Campaigning For Public Office

January 7th, 2012

I want to live in a country where publicly campaigning for political office violates a basic social contract. Where offenders are shamed for participating in a loathsome, detestable activity. Where we view it for what it actually is: a repugnant, self-aggrandizing, borderline narcissistic circus. Where the hyperbolic rhetoric, the media sensationalism, and the pandering to basic human emotions is morally disgusting.

Humans are not biologically evolved to visit Disneyland

January 16th, 2011

One of the perks (or curses, depending on how you look at it) of working for Disney was having a Silver Pass. The Silver Pass entitles employees and three friends or family members to have access to the amusement parks. Whenever friends or family visited me in LA, I usually took them down to Anaheim to spend the day at Disneyland. I went, not because I enjoyed going, because it was a spectacle and it was free. In my three years at Disney, I maybe visited the park over a dozen times. On one of my last trips, I came home, took the obligatory post-Disneyland nap (PDN) and then wrote this.

Humans are not biologically evolved
to visit Disneyland.

At around 4pm in the afternoon,
kids get whiney and annoying,
parents get grumpy.
No one looks happy trying to
maximize their dollar to fun ratio.

The breaking point comes when
fanny packs outnumber smiles.
A long day of waiting is punchuated
by brief moments of forced adrenaline.

Being voluntarily assaulted by bright colors,
the perpetual crescendos of background soundtrack,
as well as resisting a biological fixation on crowds
is exhausting.

Doing the Konami Code with AS3

December 23rd, 2010

For a project I was working on, I wanted to the ability to enter a secret string of keys on the Keyboard (e.g. the Konami code). Here’s the class to be able to do just that.

package
{
    import flash.display.*;
    import flash.ui.*;
    import flash.utils.*;
    import flash.events.*;
   
    /**
    *   This class is for creating secret codes
    *   entered on the keyboard (e.g. Konami Code)
    *   @author Matt Moore matt@cloudkid.com
    */

    public class SecretCode extends EventDispatcher
    {
        /** Event when the code entered has succeeded */
        public static const SUCCESS:String = "onSuccess";
       
        /** Event when the code has been entered bad */
        public static const FAILED:String = "onFailed";
       
        /** Event dispatched when the code listening times out */
        public static const TIMEOUT:String = "onTimeout";
       
        /** We'll save the konami code, this is the default */
        public static const KONAMI:Array = [
            Keyboard.UP, Keyboard.UP,
            Keyboard.DOWN, Keyboard.DOWN,
            Keyboard.LEFT, Keyboard.RIGHT,
            Keyboard.LEFT, Keyboard.RIGHT,
            66, //B
            65, //A
        ];
       
        /** The stage to listen to keystrokes */
        protected var __stage:DisplayObject;
       
        /** The secret code (default here is Konami) */
        protected var __code:Array;
       
        /** The limit input timer, code times out */
        protected var __timeoutTimer:Timer;
       
        /** Record the key inputs */
        protected var __keyRecord:Array = [];
       
        /** Whether this is enabled or not */
        protected var __enabled:Boolean;
       
        /**
        *   Listen for secret codes
        *   @param obj The stage to listen to keystrokes on
        *   @param timeThreshold The number of ms you have to enter the time
        *   @param code The optional array of keyboard inputs to check for
        */

        public function SecretCode(obj:DisplayObject, timeThreshold:int=5000, code:Array=null): void
        {
            __stage = obj;
           
            __code = code == null ? KONAMI : code;
           
            __timeoutTimer = new Timer(timeThreshold, 1);
           
            enabled = true;
        }
       
        /**
        *   Enable or disable this
        */

        public function set enabled(enabled:Boolean): void
        {
            __enabled = enabled;
           
            __timeoutTimer.removeEventListener(TimerEvent.TIMER, onTimeout);
            __stage.removeEventListener(KeyboardEvent.KEY_UP, onCodeInput);
            __stage.removeEventListener(KeyboardEvent.KEY_DOWN, onStartCodeInput);
           
            if (enabled)
            {
                __timeoutTimer.addEventListener(TimerEvent.TIMER, onTimeout);
                reset();
            }
        }
       
        /**
        *   Get the enabled status
        */

        public function get enabled(): Boolean
        {
            return __enabled;
        }
       
        /**
        *   Entering the code has timed out from when you hit the first key
        *   @param ev Timer Event
        */

        private function onTimeout(ev:TimerEvent): void
        {
            dispatchEvent(new Event(TIMEOUT));
            reset();
        }
       
        /**
        *   This resets listening for a code
        */

        private function reset(): void
        {
            __stage.removeEventListener(KeyboardEvent.KEY_UP, onCodeInput);
           
            __stage.removeEventListener(KeyboardEvent.KEY_DOWN, onStartCodeInput);
            __stage.addEventListener(KeyboardEvent.KEY_DOWN, onStartCodeInput);
           
            __keyRecord = [];
            __timeoutTimer.reset();
        }
       
        /**
        *   When the user starts inputting on the keyboard
        *   @param Keyboard event key down
        */

        private function onStartCodeInput(ev:KeyboardEvent): void
        {
            // The first key must be entered correctly to start listening
            if (ev.keyCode != __code[0]) return;
           
            __stage.removeEventListener(KeyboardEvent.KEY_DOWN, onStartCodeInput);
           
            __stage.removeEventListener(KeyboardEvent.KEY_UP, onCodeInput);
            __stage.addEventListener(KeyboardEvent.KEY_UP, onCodeInput);
           
            __timeoutTimer.start();
        }
       
       
        /**
        *   Record the keyboard inputs
        *   @param ev Keyboard event key up
        */

        private function onCodeInput(ev:KeyboardEvent): void
        {
            __keyRecord.push(ev.keyCode);
           
            if (__keyRecord.length < __code.length)
            {
                return;
            }
           
            if (__keyRecord.length > __code.length)
            {
                dispatchEvent(new Event(FAILED));
                reset();
                return;
            }
           
            if (__keyRecord.toString() == __code.toString())
            {
                dispatchEvent(new Event(SUCCESS));
                reset();
                return;
            }
        }
       
        /**
        *   Destroy this class. Don't use after this
        */

        public function destroy(): void
        {  
            __timeoutTimer.removeEventListener(TimerEvent.TIMER, onTimeout);
            __timeoutTimer.reset();
            __timeoutTimer = null;
           
            __keyRecord = null;
            __code = null;
           
            __stage.removeEventListener(KeyboardEvent.KEY_UP, onCodeInput);
            __stage.removeEventListener(KeyboardEvent.KEY_DOWN, onStartCodeInput);
            __stage = null;
        }
    }
}

Here’s an example of implementing the SecretCode object. In the constructor you can pass in your secret code into the constructor as an array of keyCodes. If you don’t specify anything, like below, it uses the Konami Code.

var secret:SecretCode = new SecretCode(stage, 3000);
secret.addEventListener(SecretCode.SUCCESS, onSuccess);

function onSuccess(event:Event): void
{
    trace("You have entered the secret code correctly!");
}

I Have the Best Roommate and Here’s Why

July 11th, 2010

This week, I arrived safely, albeit slight jetlagged, home from my Denver trip. I hadn’t seen my roommate Kathryn in about a week so we played catch-up in the kitchen right before bedtime. We reciprocated stories about our forth of July weekends when, throughout our conversation, we were interrupted by a periodic and faint yelp-squeal.

It sounded like it was coming from the inside of our stove. I crouched down to confirm that it was, in fact, coming from that general vicinity. Kathryn grabbed a headlamp from her room and we both crouched down with one eye to the floor. It was clear that among the thicket of dust balls was a tiny mouse caught in not one, but two traps.

Kathryn removed the drawer from underneath the oven so that we could get a better look at the mouse situation. Awhile ago, our landlord had placed sticky traps under our oven in combination with these black plastic clamp traps. Somehow the mouse had managed to find the only sticky spot not covered in pillowy gray dust while having its hind parts crushed in the clamp.

The terms of Kathryn and I’s contract for what was going to happen next were agreed upon before proceeding. It can be summarized by the following: I was going to owe her one. My role would be to stand with one foot in the kitchen and one in the hallway with a clenched fist near my mouth. Humans have long and tumultuous relationship with mice, so I felt that evolution was clearly defending my cowardice.

While Kathryn and I discussed the soundest course of action she should take, the mouse started chewing its leg in some desperate, last ditch effort to spread vermin blood all over our kitchen floor. We were clearly wasting time. Kathryn found some gloves, a brown paper bag, and a broom. She brushed the mouse and attached traps into the bag, rolled up the top and scurried out the front door. My sigh of relief was interrupted when seconds later she returned with the unopened brown bag.

Kathryn felt guilty for just leaving the yelp-squealing mouse in the trash can. The only decent thing to do was a mercy killing and the cleanest solution was drowning. Kathryn filled a large yogurt container with water and went to the back porch where she apologized profusely before committing our furry foe to a Stoneyfield Farm grave. As the unqualified medical examiner, I came to the back porch to see that there was no movement of the sticky paper.

Kathryn, you are a brave and courageous individual. Thank you. And yes, I owe you one.

Unequivocally Cold

June 17th, 2010

We all live on a silent island. It’s freezing and I shut the windows, but I’m still unequivocally cold. When I feel cold, I hear the reverberating sound of a maternal voice telling me to “put on a sweater”. I don’t even own a sweater.

The mornings are challenging. Someone throwing an iced bucket of pain on my face, and I’m instantly wide awake unable to think about anything except the things I’d soon forget. My mind grasps for a resting spot where I can watch those other memories storm by.

This morning’s restful spot was about how my friend recently said that what I’m feeling “is human”. If being human is what this is, natural selection is a cruel beast. Yet, it’s comforting to think that my genes are controlling me more than my irrational free will.

What is the evolutionary advantage to heartbreak? Does it make sure that we learn to not take love for granted? Does it force us to relentlessly pursue someone who’s not in our best interest? Does it make us hyper-sensitive to the relationships that are undoubtedly meaningful?

Hattie’s Cupcakes

May 18th, 2010

He was already running ten minutes late. His stubble and hair were the worst combination of terrifying and unsightly. If Charlie was going to make it to Hattie’s birthday then he needed to finish piping the red buttercream frosting. Red was Hattie’s favorite color and he promised hand-crafted pastries weeks ago.

He was fifteen minutes late when the last bit of frosting was on. This is getting ridiculous. He surgically placed all of the little treats into a semi-opaque shallow box designed for the singular purpose of hosting a dozen cupcakes. He placed the container inside his bag, careful not to disturb the architecture of the frosting.

In order to not be late, Charlie needed to rush four blocks as fast as he could without running. He clutched the bag to his chest speed-walking while smuggling a confectionery sleeping baby.

Charlie cracked the door to the subway station with one finger and used his right foot for the rest. His frantic, sweaty face looked around for a conveniently absent clock. Keeping the bag level with one hand, he reached for the subway pass in his back pocket. He is interrupted with a stern and deliberate, “Stop!”

A shiny badge and pleated uniform repeats the single word instruction again. In the distance, a chorus of mechanical voices says, “The train is approaching.” Charlie says, “I need to… just… if I could please… my train…” Unaffected, the badge says, “I’m going to have to take a look in your bag.”

Charlie sighs while gingerly extending his bag. The officer snatches the package and drops it onto a white plastic table. The officer shamelessly separates the zipper to reveal a frosting massacre inside the plastic box. Then, in the background Charlie hears, “The doors are about to close.”

Creating and Seamless Audio Stream in AS3

February 18th, 2010

I was frustrated that there was no ActionScript3 equivalent for setting an audio clip to Stream as you can inside of Flash. I wanted to create a seamless audio loop that was synced with a corresponding looping MovieClip. Because the audio never quite lined up on the last frame of the MovieClip inside Flash CS4, there was always an audible seam. I created a class called AudioStreamController which takes a MovieClip and a Sound object as parameters. On ENTER_FRAME the playback of the MovieClip seeks to the frame of the corresponding Sound position (assuming that the MovieClip is roughly the length of your Sound).

package
{
    import flash.events.*;
    import flash.media.*;
    import flash.display.*;
   
    public class AudioStreamController extends EventDispatcher
    {
        /** The sound channel to control sound playback */
        private var __channel:SoundChannel;
       
        /** The sound object */
        private var __sound:Sound;
       
        /** The number of times to loop the animation */
        public var loops:int = 1;
       
        /** The animatino to sync to audio */
        public var __clip:MovieClip;
       
        /** The total number of frames */
        public var __frames:int;
       
        /** The last paused position */
        public var __lastPosition:int;
       
        /**
        *   The purpose of this class is to replicate the syncing that
        *   you can do in Flash using the audio "Stream" setting
        *   @param clip The animation you want to sync
        *   @param sound The sound object you want to play
        */

        public function AudioStreamController(clip:MovieClip, sound:Sound): void
        {
            __sound = sound;
            __clip = clip;
            __frames = clip.totalFrames;
           
            stop();
        }
       
        /**
        *   Start the playback of the audio and listen for new frame enter
        *   to seek to the correct frame of the animation
        */

        public function play(): void
        {
            __channel = __sound(__lastPosition, loops);
            __clip.addEventListener(Event.ENTER_FRAME, update);
        }
       
        /**
        *   Stop and return to the beginning
        */

        public function stop(): void
        {
            if (__channel)
            {
                __channel.stop();
            }
            __lastPosition = 0;
            __clip.gotoAndStop(1);
            __clip.removeEventListener(Event.ENTER_FRAME, update);
        }
       
        /**
        *   Pause the playback and save the current position
        */

        public function pause(): void
        {
            __clip.removeEventListener(Event.ENTER_FRAME, update);
            __lastPosition = __channel.position;
            __channel.stop();
        }
       
        /**
        *   Update event called on entering new frame of the animation
        *   @param ev Enter frame event
        */

        protected function update(ev:Event): void
        {
            // This is the percentage of progress of all the loops
            var percent:Number = __channel.position / (__sound.length * loops);
           
            // The current frame over all the loops
            var f:int = Math.round((__frames - 1) * loops * percent) + 1;
           
            // The current frame gets converted into a frame on a single loop
            f = f - int(f / __frames) * __frames;

            __clip.gotoAndStop(f);

            if (percent > 0.999)
            {
                __clip.removeEventListener(Event.ENTER_FRAME, update);
                __clip.gotoAndStop(__frames);
               
                dispatchEvent(new Event(Event.COMPLETE));
            }
        }
       
        /**
        *   Destroy this controller object
        *   don't use after this point
        */

        public function destroy(): void
        {
            __clip.removeEventListener(Event.ENTER_FRAME, update);
           
            stop();
           
            __clip = null;
            __sound = null;
            __channel = null;
        }
    }
}

Exporting Layers as Separate SWFs

November 16th, 2009

Here’s another JSFL tool I created. This one will save each layer  on the current timeline (there’s also an option to export selected layers) as a separate SWFs. I find this useful for doing a batch process of transparent PNGs into SWFs. I originally made this for my co-worker Evan who uses this to export layers of animation so that he can assemble them in After Effects and manipulate the layers independently (useful for doing things like depth of field, parallax, or setting up 3D scenes). The SWFs that are generated are named according to the layer name (e.g., “my-circle” layer is exported as “my-circle.swf”).

This is Flash CS4-only. Download the extension here and run with the Adobe Extension Manager to install. Restart Flash and run under Commands > Exporting > Export All Layers or Export Selected Layers. This tool is licensed under the MIT license.