Im still searching for the definitive as3 preloader solution. Currently I use a "Root" class which is below. Problem is I still need my classes exported on the first frame which in some cases is a hefty 200k overhead before my preloader kicks in. I have all my assets later on in the piece. Im wondering what other and perhaps better systems are out there...

Code:

package 
{
	import flash.display.*;
	import flash.events.*
	import flash.text.TextField;
	import flash.ui.*
	import flash.net.*
	import GameManager
	import Constants
	import MochiBot
	
	public class Root extends MovieClip
	{
		public static var _root:MovieClip;
		
		public var VALID_URL:Array = ["http://www.blastone.com", "http://blastone.com", "http://127.0.0.1", "http://www.markfennell.com", "http://markfennell.com", "file://"]
		public var GAME_TITLE:String = "LILRACERZ"

		private var maskWidth:Number
		private var lb:int 
		private var ltl:int
		private var percent:int
		
		private var game:GameManager
		
		public function Root()
		{
			
			_root = this;
			_root.preloader.game.title.text = GAME_TITLE
			
			maskWidth = _root.preloader.preloaderBar.bar.width
			_root.preloader.preloaderBar.bar.width = 0
			
			this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onRootLoaderProgress);
			this.loaderInfo.addEventListener(Event.COMPLETE, onRootLoaderComplete);
			
			var myContextMenu:ContextMenu = new ContextMenu();
			myContextMenu.hideBuiltInItems();
			
			var item:ContextMenuItem = new ContextMenuItem( 'A Blastone.com game' );
            myContextMenu.customItems.push(item);
            item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, this.menuItemSelectHandler);
			
			this.contextMenu = myContextMenu;
			
			function onRootLoaderProgress (event:ProgressEvent):void
			{
				lb = event.bytesLoaded;
				ltl = event.bytesTotal;
				percent = lb/ltl*100;
				_root.preloader.percentage.text = String(percent)+"%";
				_root.preloader.preloaderBar.bar.width = maskWidth * lb/ltl
			}
			
			function onRootLoaderComplete (event:Event):void
			{
				_root.preloader.percentage.text = "100%";
				_root.preloader.preloaderBar.bar.width = maskWidth
				
				if(percent>=100)
				{
					init()
				}
			}
			
			function init()
			{
				var isValid = false
				var url = _root.loaderInfo.url
				//_root.gotoAndPlay("game");
				
				
				for (var i=0; i< VALID_URL.length; i++)
				{
					if (url.indexOf(VALID_URL[i]) != -1)
					{
						isValid = true
						break;
					}
				}
				if (isValid) 
				{
					playGame()
					//_root.gotoAndPlay("intro"); // intro
				}
				else 
				{
					_root.gotoAndPlay("bad");
				}
				
			}
			
			MochiBot.track(this, "8b8cfa5f");
			
		} 
		
		private function menuItemSelectHandler(event:ContextMenuEvent):void
		{
            var url:String = Constants.URL_MORE_GAMES
            var request:URLRequest = new URLRequest( url );
            try {            
                navigateToURL(request);
            }
            catch (e:Error)
			{
			}
        }
		
		public static function credits()
		{
			
		}
		
		public static function submit()
		{
			_root.gotoAndPlay("submit");
		}
		
		public static function restart()
		{
			_root.gotoAndPlay("game");
		}
		
		private function playGame()
		{
			_root.gotoAndStop("game"); // intro
			
			if (game) 
			{
				removeChild(game)
				game = null
			}
			
			game = new GameManager(stage)
			addChild(game)
		}
	}
}