AS3 PV3D Preloader

Preloading is crucial when you have to load anything that takes more than a couple seconds. I’ve never liked the popular export to frame two, movie clip on the stage containing every single asset technique either. In my opinion it always felt like a hack, and somewhat of a hassle when you have larger files. I also prefer to have a single empty key frame on the main time line, so I created this preloader. It’s essentially a wrapper swf that loads your main swf which contain all the assets. I also thought this would be the perfect opportunity to represent Papervision3D by rocking the logo. The preloader is only 10k total, and uses TweenLite. You’ll also need the latest PV3D 2.0 classes which can be found HERE.

Download Source
View Swf

Preloader.as

/**
 * AS3 PV3D Preloader v2.2
 * Copyright (c) 2009 Marco Di Giuseppe	- http://designmarco.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package
{
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.display.Stage;
	import flash.display.StageScaleMode;
	import flash.display.StageQuality;
	import flash.display.StageAlign;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import com.greensock.easing.Expo;
	import com.greensock.TweenLite;
	/**
	 * Preloader Class Loads an External swf while
	 * animating a movieclip from the Library
	 */
	public class Preloader extends Sprite
	{
		private var swf:String = "main.swf"; //name of swf we are preloading
		private var inertia:Number = 5; //amount of easing applied to progress bar
		private var wait:Number = 2; // duration of time before loading begins
		private var preloader:PreloadClip; // library movieclip of logo
		private var barRatio:Number; // length of bar divided by 100
 
		public function Preloader()
		{
			addEventListener(Event.ENTER_FRAME, checkStage, false, 0, true);
		}
 
		/**
		 * Verify that the stage has been established by the browser
		 * @param	event
		 */
		private function checkStage(event:Event):void
		{
			if (stage.stageHeight > 0 && stage.stageWidth > 0)
			{
				removeEventListener(Event.ENTER_FRAME, checkStage);
				init();
			}
		}
 
		/**
		 * Initialize Preloader
		 */
		private function init():void
		{
			stage.scaleMode = "noScale";
			stage.quality = "High";
			stage.align = "TL";
 
			preloader = new PreloadClip();
			addChild(preloader);
 
			barRatio = preloader.progress_mc.bar.width / 100;
			preloader.x = stage.stageWidth * 0.5 - preloader.width * 0.5;
			preloader.y = stage.stageHeight * 0.3;
			preloader.progress_mc.bar.width = 0;
 
			var i:int = preloader.numChildren - 1;
			var logo:Sprite;
			while (i--)
			{
				logo = preloader.getChildByName("m" + i) as Sprite;
				TweenLite.from(logo, 0.4, { scaleX:10, scaleY:10, alpha:0, delay:i * 0.1, ease:Expo.easeOut } );
			}
 
			TweenLite.delayedCall(wait, loadContent);
		}
 
		/**
		 * Begin Loading Process
		 */
		private function loadContent():void
		{
			var loader:Loader = new Loader();
			var request:URLRequest = new URLRequest(swf);
			setListeners(loader.contentLoaderInfo, true);
			if (request) loader.load(request);
		}
 
		/**
		 * Display Loading Progress
		 * @param	event
		 */
		private function progressHandler(event:ProgressEvent):void
		{
			var percentLoaded:Number = int((event.bytesLoaded / 1024) / (event.bytesTotal / 1024) * 100);
			var barWidth:Number =  barRatio * percentLoaded;
			preloader.progress_mc.loading_txt.text = String(int(percentLoaded) + "%");
			preloader.progress_mc.bar.width += (barWidth - preloader.progress_mc.bar.width) / inertia;
 
			if (percentLoaded >= 100) preloader.visible = false;
		}
 
		/**
		 * Handle possible Loading Error
		 * @param	event
		 */
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			trace("ioErrorHandler: " + event);
		}
 
		/**
		 * Add loaded swf to the display list
		 * @param	event
		 */
		private function completeHandler(event:Event):void
		{
			var main:* = event.target.content;
			TweenLite.from(main, 1, { alpha:0, delay:0.5, onStart:addChildAt, onStartParams:[main, 0], onComplete:destroy } );
			setListeners(main, false);
		}
 
		/**
		 * Remove Preloader
		 */
		private function destroy():void
		{
			if (preloader && preloader.parent)
			{
				preloader.parent.removeChild(preloader);
				preloader = null;
			}
		}
 
		/**
		 * Manage Loading Event Listeners
		 * @param	dispatcher
		 * @param	b
		 */
		private function setListeners(dispatcher:IEventDispatcher, b:Boolean):void
		{
			var state:String = b ? "addEventListener" : "removeEventListener";
			dispatcher[state](Event.COMPLETE, completeHandler);
			dispatcher[state](IOErrorEvent.IO_ERROR, ioErrorHandler);
			dispatcher[state](ProgressEvent.PROGRESS, progressHandler);
		}
	}
}

Main.as

/**
 * 	PV3D 2.0 Basic Example
 * 	@author Marco Di Giuseppe
 * 	marco (at) designmarco (dot) com
 * 	http://designmarco.com
 */
package
{
	import flash.events.Event;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.materials.BitmapAssetMaterial;
 
	public class Main extends BasicView
	{
		private var plane:Plane;
 
		public function Main()
		{
			super(0, 0, true);
			addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
		}
 
		// initialize pv3d scene
		private function init(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			_camera.focus = 100;
			_camera.zoom  = 11;
 
			var material:BitmapAssetMaterial = new BitmapAssetMaterial("image");
			material.smooth = true;
			material.doubleSided = true;
 
			plane = new Plane(material, 500, 500, 2, 2);
			plane.pitch(20);
			scene.addChild(plane);
 
			addEventListener(Event.ENTER_FRAME, render, false, 0, true);
		}
 
		private function render(event:Event):void
		{
			plane.yaw(0.75);
			singleRender();
		}
	}
}