Encouraging Stats for Unity3D as a Mobile Games Dev Platform but There’s Still a Reality Check for Non-Indie Developers

Interesting statistics from Game Developer magazine (May 2012), via Gamasutra:

…Game Developer magazine has released the results of its first-ever mobile and social developer technology survey in the May 2012 issue….

Unity topped the list of mobile game engines, with 53.1% of developers reporting using Unity compared to 39.8% using a custom engine., 17.7% using Cocos2D, 5.3% using Marmalade, and 5.3% using Corona (this question wasn’t exclusive, so the percentage count adds up to more than 100%).

I’m guessing most of the 53% are indie developers for now.

At the moment (Fri, Aug 24, 2012), I did a search for “Unity3D” on Indeed.com in all of the US, and got less than 100 job postings, many of them only mentioned Unity3D as a “nice to have”. Compared that with 8,828 jobs that mention HTML5, 12,567 for Flash (yes, still!), 2,087 for Actionscript (even after “Flash found dead in seedy San Jose motel room“) on the same date in all of the US.

I hope more Tech Directors & teams hear about Unity soon & pick it as their dev tool for mobile games & beyond. I like working in this game engine, so it’d be nice to have more job opportunities for it in more places.

Advertisements

Matrix Math Practice in AS3.0 with TweenMax & transformMatrix Plugin

package
{
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import com.greensock.TweenMax;
	import com.greensock.plugins.*;
	
	[SWF (width="500", height="500", backgroundColor="#CCCCCC", frameRate="30")]		
	public class MatrixMathTesting extends Sprite
	{
		private var mc:MovieClip = new MovieClip();
		private var wishMatrix:Matrix = new Matrix;
		
		public function MatrixMathTesting()
		{
			TweenPlugin.activate([TransformMatrixPlugin]);
			
			mc.x = 250;
			mc.y = 250;
			addChild( mc );
			
			var sq:Shape = new Shape();
			sq.graphics.beginFill( 0x000000, .5 );
			sq.graphics.drawRect( 0, 0, 100, 100 );
			sq.graphics.endFill();			
			
			mc.addChild( sq );			
			
			var ar:Array = [ [2,   0], 		//[x-scale (a), y-skew (b)]
					  		 [0.5, 1],		//[ x-skew (c), y-scale (d) ]
					   		 [mc.x, mc.y] ]; //[x-position (tx), y-position (ty)] 
			
			transformMC( wishMatrix, ar );
			
			TweenMax.delayedCall( 2, removeTransform, [wishMatrix] );
			 
		}
	
		public function transformMC( m:Matrix, arr:Array ):void 
		{
			TweenMax.to(mc, 1, {transformMatrix:{ a:arr[0][0],  b:arr[0][1], 
										          c:arr[1][0],  d:arr[1][1], 
												  tx:arr[2][0], ty:arr[2][1] }});						
		}
		
		public function transformMCSimple( m:Matrix, arr:Array ):void 
		{			
			m.a  = arr[0][0];  //	 x-scale
			m.b  = arr[0][1];  //  	 y-skew
			m.c  = arr[1][0];  //	 x-skew 
			m.d  = arr[1][1];  //		 y-scale
			m.tx = arr[2][0]; //	 x-position 
			m.ty = arr[2][1]; //	 y-position 
			
			mc.transform.matrix = wishMatrix;
		}
		
		public function removeTransform( m:Matrix ):void
		{		
			//tween back to an identity matrix		
			TweenMax.to(mc, 1, {transformMatrix:{a:1, b:0, c:0, d:1, tx:mc.x, ty:mc.y }}); 
		}
		
		public function removeTransformSimple( m:Matrix ):void
		{		
			//no anmation, back to identity matrix (removes all previous transformations)
			m.a  = 1; m.b  = 0; 
			m.c  = 0; m.d  = 1;  
			m.tx = m.tx; m.ty = m.ty;			
			
			mc.transform.matrix = m;			
		}		
		
	}
}

Quick port of “Mac Dock Style Menu with AS3.0” into a single class

Here’s a Document Class version of an ActiveTuts+ tutorial called Create a Mac Dock Style Menu with AS3.

Here’s what I changed:

  • removed each button’s dependence on 3-level deep inheritance (OverButton > DockButton > DockItem)
  • removed each Library symbol’s linkage to OverButton.as
  • simplified the menu a bit for the purposes of this example, so that only the X axis moves. It’s easy enough to add in the Y axis & scale variables, if/when needed. You should be able to extend DockMenu.as to add the extra features, like Y axis movement & Scaling or add those vars directly.
package 
{	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import com.greensock.TweenMax;
	import flash.display.DisplayObjectContainer;
	
	public class DockMenu extends MovieClip
	{					
		protected var maxXDistance:Number = 50;
		protected var menuXes:Array = []; 
		protected var menuBtns:Array = []; 
		
		public function DockMenu():void 
		{
			addEventListener( Event.ADDED_TO_STAGE, init );			
		}					
	
		public function init(e:Event=null):void
		{			
			removeEventListener( Event.ADDED_TO_STAGE, init );						
			
			//uncheck "Export for Actionscript" for each of 
            //the button mc's in the Library			
			menuBtns = [star, config, apple, photo, shop, cont ]; 
			
			for( var f:uint=0; f < 6; f++ )
			{
				menuXes[f] = menuBtns[f].x; 
				menuBtns[f].buttonMode = true;
				menuBtns[f].mouseChildren = false; 
				var bounds:Rectangle = getBounds( menuBtns[f] );
				var hit:Sprite = new Sprite();
				hit.graphics.beginFill( 0,0 );
				hit.graphics.drawRect( bounds.x, bounds.y, bounds.width, bounds.height );		
				menuBtns[f].addChild( hit );
			}
			
			stage.addEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
			stage.addEventListener( Event.MOUSE_LEAVE, mouseLeave );			
		}
		
		public function mouseMove(e:MouseEvent):void
		{								
			for( var g:uint=0; g < 6; g++ )
			{
				var xDistance:Number = mouseX - menuXes[g]; 
				xDistance = xDistance > maxXDistance ? maxXDistance : xDistance; 			
				xDistance = xDistance < -maxXDistance ? -maxXDistance : xDistance;
				var posX:Number = menuXes[g] - xDistance * 0.2; 
				TweenMax.to( menuBtns[g], .2, { x:posX } );		
			}		
		}
				
		public function mouseLeave(e:Event):void
		{			
			for( var h:uint=0; h < 6; h++ )
				TweenMax.to( menuBtns[h], .3, { x:menuXes[h] } );
		}
	}	
}

Flash Builder & Apparat example: BUILD FAILED “java.io.IOException: Cannot run program “…/mxmlc” (in directory “…/apparat-ant-example”): error=2, No such file or directory

Made sure my Flash Builder 4.5 on OSX 10.5 is set to use Java 1.6 (out of the box it came set to use JVM 1.5).

Followed the instructions on webdevotion.be and cultcreative.com.

When it came time to do “Run As > Ant Build” I kept getting this error:

Buildfile: /your_path_to_example_folder/apparat-ant-example/build/build.xml
clean:
compile:

BUILD FAILED
/your_path_to_example_folder/apparat-ant-example/build/build.xml:64:
Execute failed: java.io.IOException: Cannot run program "/Applications/Adobe%20Flash%20Builder%204.5/sdks/4.5.0/bin/mxmlc"
(in directory "/your_path_to_example_folder/apparat-ant-example"): error=2, No such file or directory

Total time: 860 milliseconds

After trying a bunch of things, it turned out it was a permissions problem.

To fix it, I swapped Flex SDK to one outside of /Applications/ folder. Inside the project’s build.properties I updated FLEX_HOME line to:

FLEX_HOME=/your_path_to_sdk/Flex_SDKs/4.1.0

instead of

FLEX_HOME=/Applications/Flash%20Builder%204.5/sdks/4.5.0

and it worked.

Robotlegs, Part 2: Adding ImageLoader & TweenMax

Expanding on the previous Robotlegs entry. The original source code is generously provided by hubflanger. I’m modifying her code to show images using two popular asset loading & animation libraries. To do this we have to modify the XML data file and image preloading, processing & display code in these 3 classes: LoaderMaxDataService, SectionVO & SectionContainer.

Updated LoaderMaxDataService:

package com.hubflanger.robotlegsdemo.service
{
	import com.hubflanger.robotlegsdemo.model.vo.SectionVO;
	import com.hubflanger.robotlegsdemo.model.SiteModel;
	import com.hubflanger.robotlegsdemo.events.SystemEvent;
	
	import com.greensock.events.LoaderEvent;
	import com.greensock.loading.ImageLoader;
	import com.greensock.loading.LoaderMax;
	import com.greensock.loading.XMLLoader;
	import com.greensock.loading.display.ContentDisplay;
	
	import flash.events.Event;
	import flash.net.*;
	
	import org.robotlegs.mvcs.Actor;
		
	/**
	 * A Service class that handles loading and parsing of the site's xml data.
	 */	
	public class LoaderMaxDataService extends Actor implements ISiteDataService
	{
		/**
		 * Inject the <code>SiteModel</code> Singleton.
		 */		
		[Inject]
		public var model				:SiteModel; 		
		private var queue				:LoaderMax; 		
		private var xml					:XMLLoader;

		public function LoaderMaxDataService()
		{ 			
			LoaderMax.activate([XMLLoader, ImageLoader]);				
		}
				
		public function loadData():void 
		{			
			var xml:XMLLoader = new XMLLoader("assets/data.xml", 
											  {name:"mainXML", 
											  onComplete:xmlComplete, 
											  estimatedBytes:4000});
			xml.load();						
		}
		
		/**
		 * Handler for the XMLLoader's onComplete.	
		 * <p>Preloads the images</p>
		 */			
		private function xmlComplete(e:LoaderEvent):void
		{
			xml = e.target as XMLLoader; 
			
			queue = new LoaderMax({name:"mainQueue", 
								   onProgress:qProgressHandler,
								   onComplete:qCompleteHandler,
								   onError:qErrorHandler});

			var sections:XMLList = xml.content.sections.section; 			
			for each (var section:XML in sections) 
			{
				queue.append(new ImageLoader(section.img.@src, 
												 {name:"image_" + section.@id,											
												  alpha:0,
												  visible:false,											  											
												  container:this}));					
			}						
			
			queue.load();	
		}

		private function qProgressHandler(e:LoaderEvent):void 
        { 
            trace("progress: " + e.target.progress); 
        }
		private function qErrorHandler(e:LoaderEvent):void
        { 
            trace("qErrorHandler(): error occured with " + e.target + ": " + e.text); 
        } 
		private function qCompleteHandler(e:LoaderEvent):void 
		{
			trace(e.target + "queue complete");							
			imagesCompleteHandler();						
		}			
		 		 
		/**
		 * Process content data after images are preloaded.	
		 * <p> Tell the rest of the application when data is ready.</p>
		 */				 
		private function imagesCompleteHandler():void 
		{			
			model.header = xml.content.header.text(); 
			var sections:XMLList = xml.content.sections.section; 
			
			for each (var section:XML in sections) 
			{
				var sectionVO:SectionVO = new SectionVO(section.@id,
														section.label.toString(),
														LoaderMax.getContent("image_" + section.@id), 
														section.content.toString());				
				
				model.sectionsList.push(sectionVO);
				model.sectionsHash[sectionVO.id] = sectionVO;
			}			
			
			model.defaultSection = model.sectionsList[0].id;
			
			dispatch(new SystemEvent(SystemEvent.INIT_VIEW, false));					
		}				
	}
}

A few minor changes to SectionVO, to accomodate the new image property:

package com.hubflanger.robotlegsdemo.model.vo
{
	import com.greensock.loading.display.ContentDisplay;
	
	public class SectionVO
	{
		private var _id:String;
		private var _label:String;
		private var _image:ContentDisplay;
		private var _content:String;
		
		/**
		 * A custom  object for storing Section node data
		 */
		public function SectionVO( id:String, label:String, img:ContentDisplay, content:String )
		{
			_id = id;
			_label = label;
			_image = img;
			_content = content;
		}

		public function get id():String
		{
			return _id;
		}
		
		public function get label():String
		{
			return _label;
		}

		public function get image():ContentDisplay
		{
			return _image;
		}
		
		public function get content():String
		{
			return _content;
		}
	}
}

And finally, the addition of a Sprite image container & image display code with TweenMax:

package com.hubflanger.robotlegsdemo.view.components
{
	import com.greensock.TweenMax;

	import com.hubflanger.robotlegsdemo.model.vo.SectionVO;
	
	import flash.display.*;
	import flash.text.*;
	import flash.utils.Dictionary;
	
	/**
	 * The display container for the section content.
	 */	
	public class SectionContainer extends Sprite
	{
		private var sectionsHash:Dictionary = new Dictionary();
		private var textField:TextField;
		private var img:Sprite;
		
		/**
		 * The constructor. 
		 * <p>
		 * Creates a Shape object as background. Creates a TextField 
		 * for the content copy and a Sprite to hold images.
		 */	
		public function SectionContainer()
		{
			var bg:Shape = new Shape();
			bg.graphics.beginFill(0xF9E5C2);
			bg.graphics.drawRect(0, 0, 550, 400);
			bg.graphics.endFill();
			addChild(bg); 
				
			var tf:TextFormat = new TextFormat();
			tf.font = "Helvetica";
			tf.color = 0x4B1E18;
			tf.size = 12;
			
			textField = new TextField();
			textField.x = 222;
			textField.y = 81;
			textField.width = 310;
			textField.height = 290;
			textField.multiline = true;
			textField.wordWrap = true;
			textField.defaultTextFormat = tf;
			addChild(textField);
			
			img = new Sprite();
			img.x = 12;
			img.y = 95;
			addChild(img);			
		}
		
		/**
		 * Assigns a Dictionary object to the <code>sectionsHash</code> property.
		 *  
		 * @param hash A Dictionary instance containing <code>SectionVO</code>
		 * objects with Section IDs as key.
		 */		
		public function init(hash:Dictionary):void
		{
			sectionsHash = hash;
		}
		
		/**
		 * Retrieves the <code>SectionVO</code> object associated with the 
		 * Section ID and and populates the <code>textField</code> with the 
		 * value of its <code>content</code> property. Populates <code>img</code>
		 * with <code>SectionVO</code>'s value of <code>image</code>. 
		 *
		 * @param str The String ID of the Section selected.
		 */
		public function update(id:String):void
		{
			var sectionVO:SectionVO = sectionsHash[id];
			textField.htmlText = sectionVO.content;			

			cleanImgHolder(img);			
			img.addChild(sectionVO.image);
			TweenMax.to(sectionVO.image, 0.66, {autoAlpha:1});											
		}
		
		private function cleanImgHolder(i:Sprite):void 
		{
			if(i.numChildren > 0) { 
				TweenMax.to(i.getChildAt(0), 0, {autoAlpha:0});		
				i.removeChildAt(0);
			}
		}
	}
}

Don’t forget to update the XML file to contain an “img” element with an “src” attribute:

 <!-- ... -->
		<section id="home">
			<label>Home</label>
			<img src="images/1.jpg" />
			<content>
				<p>Lorem ipsum dolor sit amet...</p>
			</content>
		</section>
<!-- ... -->

AS3.0 Signals example juxtaposed with native version

AS3.0 Signals is an event handling framework from Robert Penner that’s gaining popularity lately. There’s a good video tutorial by John Lindquist and tutorials here.

Here’s a quick comparison of an old XML processing class written both ways for comparison. For this simple example, Signals was about 10 to 50 milliseconds faster than using regular AS3 events. The results varied a lot each time I compiled.

Using the Signals framework for events:

XML processing class:

package com.timshaya.net
{
	import org.osflash.signals.Signal;
	import org.osflash.signals.natives.NativeSignal;
	
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;	

	public class XmlGrabber 
	{		
		private var loadDone				:NativeSignal;									
		public var dataDone					:Signal;										
		public var cityItems				:Array = [];								

		private var xmlData					:XML;		
		private var loader					:URLLoader;
		private var reqst					:URLRequest;
		private var trgt					:URLLoader;
		
		public function XmlGrabber(pth:String):void 
		{
			loader = new URLLoader(); 
			reqst = new URLRequest(pth);
						
			dataDone = new Signal();	
			loadDone = new NativeSignal(loader, Event.COMPLETE, Event); 
			loadDone.addOnce(loadCompleted);					
			
			loader.load(reqst);	
		}	
		
		public function loadCompleted(e:Event):void 
		{
			var trgt:URLLoader = URLLoader(e.target);
			xmlData = new XML(trgt.data); 
			//trace(xmlData);
			
			if (trgt!=null) 
			{
				for each (var a:XML in xmlData.evnt) 
				{
					cityItems.push(a); 
					//trace("\n cityItems[a]: " + a.@city + "\n"); 
				} 													
			} else trace("error: check your data & datatype");
			
			dataReady();
		}
		
		public function dataReady():void 
		{	
			dataDone.dispatch(); 
		}
	}
}

Test class:

package 
{	
	import org.osflash.signals.Signal;	
	import org.osflash.signals.natives.NativeSignal;
	import com.timshaya.net.XmlGrabber; 	
	
	import flash.display.Sprite;	
	import flash.events.Event;	
	import flash.utils.getTimer;

	[SWF (width="600", height="400", backgroundColor="#FFFFFF", frameRate="30")]	
	public class Test extends Sprite 
	{	
		private var addToStage				:NativeSignal;
		private var xml						:XmlGrabber;		
		private var xmlPth                  :String = "xml/"; 
		private var xmlName  				:String = "events.xml"; 				
		private var timer					:Number;
		
		public function Test():void 		
		{										
			addToStage = new NativeSignal(this, Event.ADDED_TO_STAGE, Event); 
			addToStage.addOnce(initApp);			
		}

		public function initApp(e:Event):void 
		{
			timer = getTimer();
			
			xml = new XmlGrabber(xmlPth + xmlName);
			xml.dataDone.add(createPage); 									
		}

		public function createPage():void 
		{							
			trace("Test::createPage()");		
			trace("\t time elapsed: " + (getTimer() - timer));			
						
			trace("\t xml.cityItems[0].@city = " + xml.cityItems[0].@city); 
			trace("\t xml.cityItems[0].@state = " + xml.cityItems[0].@state);			
		} 				
	}
}

Same code using native AS3 events:

XML processing class:

package com.timshaya.net
{
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;	
	import flash.events.EventDispatcher;

	public class XmlGrabberOld extends EventDispatcher 
	{		
		public var cityItems				:Array = [];		

		private var xmlData					:XML;		
		private var loader					:URLLoader;
		private var reqst					:URLRequest;
		private var trgt					:URLLoader;

		public static var DATA_READY		:String	= "list_ready";
		
		public function XmlGrabberOld(pth:String):void 
		{
			loader = new URLLoader(); 
			reqst = new URLRequest(pth);
			loader.load(reqst);
			loader.addEventListener(Event.COMPLETE, listOnComplete, false, 0, true);	
		}
		
		private function listOnComplete(e:Event):void
		{			
			var trgt:URLLoader = URLLoader(e.target);
			xmlData = new XML(trgt.data);
			//trace(xmlData);
			
			if (trgt!=null) 
			{
				for each (var a:XML in xmlData.evnt) 
				{
					cityItems.push(a); 
					//trace("\n cityItems[a]: " + a.@city + "\n"); 
				} 					
			} else trace("error: check your data & datatype");			

			dataReady();
		}
		
		private function dataReady():void
		{
			dispatchEvent(new Event(XmlGrabberOld.DATA_READY));
		}
		
	}
}

Test class:

package 
{		
	import com.timshaya.net.XmlGrabberOld;

	import flash.display.Sprite;	
	import flash.events.Event;	
	import flash.utils.getTimer;

	[SWF (width="600", height="400", backgroundColor="#FFFFFF", frameRate="30")]	
	public class TestOld extends Sprite 
	{	
		private var xml						:XmlGrabberOld;		
		private var xmlPth                  :String = "xml/"; 
		private var xmlName  				:String = "events.xml"; 		
		private var timer					:Number;
		
		public function TestOld():void 		
		{								
			addEventListener(Event.ADDED_TO_STAGE, initApp);		
		}

		public function initApp(e:Event):void 
		{
			timer = getTimer();
		
			xml = new XmlGrabberOld(xmlPth + xmlName);
			xml.addEventListener(XmlGrabberOld.DATA_READY, createPage);											
		}

		public function createPage(e:Event):void 
		{						
			trace("TestOld::createPage()");		
			trace("\t time elapsed: " + (getTimer() - timer));		
			
			trace("\t xml.cityItems[0].@city = " + xml.cityItems[0].@city); 
			trace("\t xml.cityItems[0].@state = " + xml.cityItems[0].@state);						
		} 						
		
	}
}

Sample xml file, events.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<evnts>		
	
	<evnt lnk="test.aspx?c=0" city="Atlantic City" state="New Jersey" />
	<evnt lnk="test.aspx?c=1" city="Clifton" state="New Jersey" />	
	<evnt lnk="test.aspx?c=2" city="Allentown" state="Pennsylvania" />
	<evnt lnk="test.aspx?c=3" city="Akron" state="Ohio" />
	<evnt lnk="test.aspx?c=4" city="Wichita Falls" state="Texas" />
	<evnt lnk="test.aspx?c=5" city="Austin" state="Texas" />
	<evnt lnk="test.aspx?c=6" city="Orlando" state="Florida" />
	<evnt lnk="test.aspx?c=7" city="Atlanta" state="Georgia" />
	<evnt lnk="test.aspx?c=8" city="San Francisco" state="California" />
	<evnt lnk="test.aspx?c=9" city="Los Angeles" state="California" />
	<evnt lnk="test.aspx?c=10" city="San Diego" state="California" />	
	
</evnts>

Instantiating SlideShoPro in an AS3.0 Class

A simple user class:

package
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;

	import com.slideshow.MySlideShowPro;

	public class Main extends Sprite
	{
		private var mssp:DisplayObjectContainer;

		public function Main()
		{
			mssp = new MySlideShowPro(500, 350); //(width, height)
			mssp.x = 20;
			mssp.y = 20;
			addChild(mssp);
		}

	}
}

A sample basic SlideShowPro class:

package com.slideshow
{
	import flash.display.Sprite;
	import net.slideshowpro.slideshowpro.*;

	public class MySlideShowPro extends Sprite
	{
		//http://wiki.slideshowpro.net/SSPplayer/API-API
		private var myssp:SlideShowPro;

		public function MySlideShowPro(w:int, h:int)
		{
			//make sure SlideShowPro is set for Export in your Library, or SWC/SWF asset files
			myssp = new SlideShowPro(this);

			myssp.setSize(w, h);

			myssp.xmlFilePath = "xml/slides.xml";
			myssp.xmlFileType = "Default";

			/*
			the commented out lines, like:
			//myssp.navButtonGlowAlpha = .25;
			give error "1119: access of possibly undefined property..."
			*/

			myssp.navAppearance = "Always Visible";
			myssp.navBackgroundAlpha = 1;
			myssp.navBackgroundColor = 0x121212;
			myssp.navButtonsAppearance = "All Visible";
			myssp.navGradientAlpha = .3;
			myssp.navGradientAppearance = "Glass Dark";
			myssp.navButtonColor = 0xEEEEEE;
			//myssp.navButtonGlowAlpha = .25; 				//error 1119
			//myssp.navButtonGradientAlpha = .6;			//error 1119
			myssp.navButtonInactiveAlpha = .4;
			//myssp.navButtonRolloverColor = 0xFFFFFF;		//error 1119...
			myssp.navButtonShadowAlpha = .6;
			//myssp.navButtonShadowStyle = "Under";
			//myssp.navLinkAnimate = "On";
			myssp.navLinkAppearance = "Numbers";
			//myssp.navLinkActiveColor = 0xEEEEEE;
			//myssp.navLinkInactiveColor = 0x999999;
			myssp.navLinkPreviewAppearance = "Visible";
			myssp.navLinkPreviewBackgroundAlpha = 1;
			myssp.navLinkPreviewBackgroundColor = 0xFFFFFF;
			myssp.navLinkPreviewScale = "Proportional";
			myssp.navLinkPreviewSize = [100,100];
			myssp.navLinkPreviewStrokeWeight = 1;
			myssp.navLinkRolloverColor = 0xFFFFFF;
			//myssp.navLinkShadowAlpha = .6;
			myssp.navLinksBackgroundAlpha = 1;
			myssp.navLinksBackgroundColor = 0x000000;
			//myssp.navLinksBackgroundShadowAlpha = .6;
			myssp.navLinkSpacing = 8;
			myssp.navNumberLinkSize = 9;
			myssp.navPosition = "Bottom";
			myssp.navThumbLinkInactiveAlpha = 1;
			myssp.navThumbLinkSize = [16,16];
			myssp.navThumbLinkStrokeWeight = 1;

			myssp.albumBackgroundAlpha = 1;
			myssp.albumBackgroundColor = 0x303030;
			myssp.albumDescColor = 0xCCCCCC;
			myssp.albumDescSize = 9;
			myssp.albumPadding = 8;
			myssp.albumPreviewScale = "Proportional";
			myssp.albumPreviewSize = [54,41];
			myssp.albumPreviewStrokeColor = 0xFFFFFF;
			myssp.albumPreviewStrokeWeight = 1;
			myssp.albumPreviewStyle = "Inline Left";
			myssp.albumRolloverColor = 0x262626;
			myssp.albumStrokeAppearance = "Visible";
			myssp.albumStrokeColor = 0x141414;
			myssp.albumTitleColor = 0xFFFFFF;
			myssp.albumTitleSize = 10;
			myssp.audioAutoStart = "On";
			myssp.audioLoop = "Off";
			myssp.audioPause = "Off";
			myssp.audioVolume = .8;
			myssp.autoFinishMode = "Switch";
			myssp.cacheContent = "None";
			myssp.captionAppearance = "Overlay on Rollover (if Available)";
			myssp.captionBackgroundAlpha = .6;
			myssp.captionBackgroundColor = 0xFFFFFF;
			myssp.captionElements = "Header and Caption";
			myssp.captionHeaderBackgroundAlpha = 0;
			//myssp.captionHeaderPadding = [6,6,2,6];
			myssp.captionHeaderText = "{imageTitle}";
			//myssp.captionHeaderTextColor = 0xEEEEEE;
			myssp.captionPadding = [2,6,6,6];
			myssp.captionPosition = "Top";
			myssp.captionTextAlignment = "Left";
			myssp.captionTextColor = 0xAAAAAA;
			//myssp.captionTextShadowAlpha = 0;
			myssp.captionTextSize = 9;
			myssp.contentAlign = "Center";
			myssp.contentAreaAction = "Launch Hyperlink";
			myssp.contentAreaBackgroundAlpha = 1;
			myssp.contentAreaBackgroundColor = 0x161616;
			myssp.contentAreaInteractivity = "Action Area Only";
			myssp.contentAreaStrokeAppearance = "Visible";
			myssp.contentAreaStrokeColor = 0x262626;
			myssp.contentFrameAlpha = 1;
			myssp.contentFrameColor = 0x262626;
			myssp.contentFramePadding = 0;
			myssp.contentFrameStrokeAppearance = "Hidden";
			myssp.contentFrameStrokeColor = 0x333333;
			myssp.contentOrder = "Sequential";
			myssp.contentScale = "Downscale Only";
			myssp.contentScalePercent = 1;
			myssp.contentWatermark = "";
			myssp.contentWatermarkAlign = "Bottom Right";
			myssp.directorLargePublishing = "On";
			myssp.directorLargeQuality = 80;
			myssp.directorLargeSharpening = 1;
			myssp.directorThumbQuality = 60;
			myssp.directorThumbSharpening = 1;

			myssp.displayMode = "Auto";
			myssp.feedbackBackgroundAlpha = .3;
			myssp.feedbackBackgroundColor = 0x000000;
			myssp.feedbackHighlightAlpha = .8;
			myssp.feedbackHighlightColor = 0xFFFFFF;
			myssp.feedbackPreloaderAlign = "Center";
			myssp.feedbackPreloaderAppearance = "Beam";
			myssp.feedbackPreloaderPosition = "Inside Content Area";
			myssp.feedbackPreloaderScale = 1;
			myssp.feedbackPreloaderTextSize = 12;
			myssp.feedbackTimerAlign = "Top Right";
			myssp.feedbackTimerAppearance = "Visible";
			myssp.feedbackTimerPosition = "Inside Content Area";
			myssp.feedbackTimerScale = 1;
			myssp.feedbackVideoButtonScale = 1;
			myssp.fullScreenReformat = "On";
			myssp.fullScreenTakeOver = "On";
			myssp.galleryAppearance = "Visible";
			myssp.galleryBackgroundAlpha = 1;
			myssp.galleryBackgroundColor = 0x1C1C1C;
			myssp.galleryColumns = 2;
			//myssp.galleryContentShadowAlpha = 0;
			myssp.galleryOrder = "Left to Right";
			myssp.galleryPadding = 10;
			myssp.galleryRows = 4;
			myssp.galleryNavActiveColor = 0x303030;
			myssp.galleryNavAppearance = "Visible";
			myssp.galleryNavInactiveColor = 0x000000;
			myssp.galleryNavRolloverColor = 0x262626;
			myssp.galleryNavStrokeAppearance = "Visible";
			myssp.galleryNavStrokeColor = 0x141414;
			myssp.galleryNavTextColor = 0xCCCCCC;
			myssp.galleryNavTextSize = 9;
			myssp.keyboardControl = "On";
			//myssp.loop = "Off";
			myssp.mediaPlayerAppearance = "Visible on Rollover";
			myssp.mediaPlayerBackgroundAlpha = .25;
			myssp.mediaPlayerBackgroundColor = 0x000000;
			myssp.mediaPlayerBufferColor = 0x000000;
			myssp.mediaPlayerButtonColor = 0xFFFFFF;
			myssp.mediaPlayerElapsedBackgroundColor = 0xFFFFFF;
			myssp.mediaPlayerElapsedTextColor = 0x000000;
			myssp.mediaPlayerPosition = "Bottom";
			myssp.mediaPlayerProgressColor = 0xCCCCCC;
			myssp.mediaPlayerScale = .8;
			myssp.mediaPlayerTextColor = 0x999999;
			myssp.mediaPlayerTextSize = 9;
			myssp.mediaPlayerVolumeBackgroundColor = 0x000000;
			myssp.mediaPlayerVolumeHighlightColor = 0xCCCCCC;
			myssp.panZoom = "Off";
			myssp.panZoomDirection = "Random";
			myssp.panZoomFinish = "Off";
			myssp.panZoomScale = [1,1.2];
			myssp.permalinks = "Off";
			myssp.smoothing = "On";
			//myssp.soundEffects = "";
			//myssp.soundEffectsVolume = .4;
			myssp.textStrings = ["Previous Screen","Next Screen","Screen","of","No caption","No title","Playing","Paused","Click play to start audio"];
			myssp.toolAppearanceContentArea = "Hidden";
			myssp.toolAppearanceNav = "Visible";
			myssp.toolColor = 0x222222;
			myssp.toolDelayContentArea = 0;
			myssp.toolDelayNav = .5;
			myssp.toolLabels = ["Gallery","Previous Group","Previous","Next","Next Group","Pause","Play","Full Screen","Normal Screen","Open Link"];
			myssp.toolTimeoutContentArea = 0;
			myssp.transitionLength = 2;
			myssp.transitionPause = 4;
			myssp.transitionDirection = "Left to Right";
			myssp.transitionStyle = "Cross Fade";
			myssp.typeface = "Lucida Grande,Lucida Sans Unicode,Verdana,Arial,_sans";
			//myssp.typefaceAntiAlias = "Advanced";
			myssp.typefaceEmbed = "Off";
			myssp.videoAutoStart = "On";
			myssp.videoBufferTime = 0.1;
		}
	}
}