My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
EXAMPLES  
loose code examples
Updated Feb 4, 2010 by brandonflowers

Choose your own Tween Library

to decouple Tweener from the LayoutManager pass tweens in functions to the action sequence like :

myActionSequence.push(function():void
{
   LayoutManager.addChild(mc);
   TweenLite.to( mc, 0.1, {alpha:1});
});

you could accomplish this with a sequence function but anonymous functions get swept by garbage collection once they are done and lost reference.

Author: Jovan Alleyne


GLOBAL PACKAGES

Commonly we have layout elements that are global, such as logos and homescreen buttons. we may transfer them from state to state to allow garbage collection, which is a pain.

to get around that here is one solution that should work in most cases.

Define your display object:

package com.companyName.clientName.states
{
import flash.display.Sprite;

public var packageElement : Sprite = new Sprite( );

}

Define your event handler method:

package com.companyName.clientName.projectName.states
{
import org.hive.managers.StateManager;
import flash.events.MouseEvent;

public function packageHandler( e:MouseEvent ):void
{
StateManager.switchState( new CustomState( ), e );
}

}

setup your listeners once probably inside a conditional:

import org.hive.states.packageElement;
import org.hive.states.packageHandler;

packageElement.addEventListener( MouseEvent.CLICK, packageHandler );

Note: .as class files should be named the same as the property or method and can only implement one property or method per file.

Author: Jovan Alleyne


GOPHR Webservice

If you are working with .NET WSDL and need a library to handle soap, look no further than Carlo's gophr library. It does all the heavy lifting by pulling down the wsdl, exposing the web methods, and sending/receiving the soap requests. He even provides a class to completely remove the xml namespaces and turn them in straight up xml.

I've used this library a few times now and added it to 0.2 release of Hive where I've added some modifications including deeper error handling and the ability to add a soap authentication header. In my project, I like to take his Webservice class and extend to ProjectNameWebserivce with a WebService instance called "ws" and include the following method for setup:

public function createConnection( includeHeader:Boolean = false, headerNodeObjArray:Array = null ):void
		{
			
			ws = new WebService();
			
			if ( includeHeader ) WebService(ws).setHeader( headerNodeObjArray );
			ws.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, true);
			ws.addEventListener(Event.CONNECT, campaignConnectHandler);
			ws.connect(_wsdlPath, true);
			
			ws.addEventListener(WebServiceErrorEvent.EVENT_WSDL_ERROR, wsdlErrorHandler, false, 0, true);
			
			ws.cacheResults = true;
			
		}	

I've also provided a class in the xml folder that works with (instead of nuking) the soap namespaces, and turns it into an array of objects. You may need to examine your raw response and the xmlns to tweak it accordingly.

If you find that you have to hit a webservice multiple times and it fails to return a result, try setting that cacheResults to false.

This library has been tested against .NET 3.5 with great results.

author: brandon flowers


TYPE CONVERSION

Its been a constant thing we have had to do since day 1 of developing in AS3. Example events have a target property which is typed as a base class of DisplayObject. Now lets say your target object is actually a custom type like MyCustomImage which extends Sprite and has a custom property imageTitle.

calling event.target.imageTitle would throw a compiler error reporting the property might be undefined.

a common way to get around this is to use (event.target as MyCustomImage).imageTitle, the limitation with that is your IDE does not understand the type conversion thus code hinting does not function. To work around this and even just to be a bit more elegant this syntax accomplishes the same MyCustomImage(event.target).imageTitle.

Note: with both methods be sure that the class you are trying to convert an object to is part of that objects prototype chain or a null result will be returned in either case and you will throw a runtime error.

Author: Jovan Alleyne


USING TWEENER WITH SEQUENCER

This demonstrates how to set the state of a new movieclip and then pass it into an action sequence called "showPreloader" and use the tweener object to animate it.

Sample:

preloader_mc = new Preloader( infoObject );
preloader_mc.x = 250;
preloader_mc.y = 250;
preloader_mc.scaleX = 0;
preloader_mc.scaleY = 0;
preloader_mc.rotation = 90;
preloader_mc.alpha = 0;

showPreloader.push({scope:preloader_mc, time:1, transition:"linear", scaleX : 1, scaleY: 1, alpha:1});

showPreloader.push({scope:preloader_mc, time:2, rotation:0, transition:"easeOutExpo" });
showPreloader.push({scope:preloader_mc, time:2, transition:"easeOutExpo", x : 600 });

StateManager.playSequence( showPreloader );

In the above sequence, all those objects are fired at the same time. If you want to stack them, and have them fire one after another use: showPreloader.push(new SequenceDelay(2000)); between each object like so:

showPreloader.push({scope:preloader_mc, time:2, transition:"linear", scaleX : 1, scaleY: 1, alpha:1, x: preloaderCenterX, y: preloaderCenterY});
showPreloader.push(new SequenceDelay(2000));
showPreloader.push({scope:preloader_mc, time:1, transition:"easeOutExpo" });
showPreloader.push(new SequenceDelay(2000));
showPreloader.push({scope:preloader_mc, time:2, transition:"easeOutExpo", rotation:0 });

Author:Brandon Flowers


USE LOADMANAGER TO CREATE A BUTTON WITH ROLLOVER AND ROLLOUT

private var animal_mc:MovieClip = new MovieClip();

private function setupButton():void
{

                        animal_mc.buttonMode = true;
                        animal_mc.addEventListener(MouseEvent.ROLL_OVER, buttonRollOverHander);
                        animal_mc.addEventListener(MouseEvent.ROLL_OUT, buttonRollOutHander);
                        var animalRollOver:MovieClip = new MovieClip();
			var animalRollOut:MovieClip = new MovieClip();
			
			animalRollOver.name = "animalRollOver";
			animalRollOut.name = "animalRollOut";
			
			animal_mc.addChild( LoadManager.getLoaderByName('navAnimalRollOver'));
			animal_mc.addChild( LoadManager.getLoaderByName('navAnimalRollOut'));
			
			animal_mc.getChildByName("animalRollOver").visible = false; 
			animal_mc.getChildByName("animalRollOut").visible = true;
}

Author:Brandon Flowers


FINDING STAGE HEIGHT AND WIDTH FROM WITHIN ANY CLASS IN YOUR APPLICATION

var stageHeight = StateManager.layoutManager.stageHeight;
var stageWidth = StateManager.layoutManager.stageWidth;

READING FLASH VARS

If you're looking for a flashvar named "location" to can access it like so:

LayoutManager.stage.root.loaderInfo.parameters.location

you can also cycle through the parameters to find other FlashVars

Author: Brandon Flowers


CHECKING A SEQUENCE

You can find out if a current sequence is playing by checking the sequencer on the StateManager like so:

private function acceptHandler(e:Event){
if ( StateManager.sequencer.currentSequence.name != "mySequenceName" )
playNextSequence();
}
}

This will play the next sequence once and not play it again if the user quickly clicks on the accept button.


STATE CLOSE METHOD

To make an object eligible for garbage collection all external references to that object and its properties must be removed ( set to null ). Or otherwise determined by the FP9 mark and sweep method of garbage collection.

As with the public override create( ):ActionSequence method, there is a similar way to close a sequence. And as you may expect its called the close method public override close( ):CloseSequence.

This method differs in that is must return a CloseSequence or null. A CloseSequence extends ActionSequence but does not give access to the state related events and properties such as nextState.

public override function close( ):CloseSequence
{
    layoutManager.removeChild( displayObject );
    
    var closeSequence:CloseSequence = new CloseSequence( 'testCloseSequence' );
    closeSequence.push( {scope: displayObject2, time:1, alpha:0, onComplete:layoutManager.removeChild, onCompleteParams:[displayObject2] );

    return closeSequence;
}

Author: Jovan Alleyne


REMOVING DISPLAY OBJECTS USING A SEQUENCE

at the end of your sequence, you can easily remove display objects through the layoutManager on the onComplete event like so:

mySequence.push({scope:my_mc, time:1, alpha:0, transition:"linear", onComplete:layoutManager.removeChild, onCompleteParams:[my_mc]});

Author:Brandon Flowers


LOAD AN IMAGE AND APPLY BITMAP SMOOTHING VIA AN ANONYMOUS FUNCTION

                private function loadPhoto(photoPath:String, ldrName:String):void
		{
			
			 var ldr:Loader = new Loader();
			 var urlReq:URLRequest = new URLRequest(photoPath);
			ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, addLoader(ldr) );

			 ldr.load(urlReq);
	
		}
		
		private function addLoader(ldr:Loader ):Function
		{
			return function(e:Event)
			{							
				var bmp:Bitmap = new Bitmap( Bitmap(ldr.content).bitmapData, "auto", true);
								
				var mc:MovieClip = new MovieClip();
				mc.addChild(bmp);
                                addChild(mc); 
                        }
                }

APPLY BITMAP SMOOTHING TO IMAGES ALREADY LOADED INTO LOADMANAGER

myImageHolder.addChild( new Bitmap( LoadManager.getLoaderByName('myImageId').content.bitmapData, "auto", true));

Author:Brandon Flowers


ON ENTER FRAME EVENT

If you want an individual state to listen to an enterframe event, you can add an event listener to your Main class and dispatch the enterframe event through the StateManager so that each state could listen to that event.

example:

// Main.as

	private function init() 
		{			
			
			trace ("Main / init()");
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		
		private function onEnterFrame(e:Event):void
		{
			StateManager.layoutManager.dispatchEvent(new Event("MAIN_ENTER_FRAME"));
		} 

// State.as

private function catchEnterframe()
		{
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
			StateManager.layoutManager.addEventListener("MAIN_ENTER_FRAME", onEnterFrame);
		}
		
		private function onEnterFrame(e:Event)
		{
			//trace ("running");
		}

Author:Brandon Flowers


USING THE SAME GRAPHIC FOR MULTIPLE SPRITES THROUGH LOADMANAGER

If you want to use the same bitmap graphic for multiple sprites, you need to make sure that each bitmap has a unique label. In the below example, I use a loaderSet and loadManager to load 1 schoolyard graphic and 8 snowballs with unique names that each point to the same graphic.

// LoadingState.as

var mySchool:Yard = new Yard("kinglear", 100, 200);

var snowballFightGraphicNameArray:Array = new Array();
			
			snowballFightGraphicNameArray.push(mySchool);
			
			for (var snowballCounter:uint; snowballCounter< snowballCounter; snowballCounter++)
			{
				var snowballName:String = "snowball" + snowballCounter;
				var snowballPath:String = "images/objects/" + fightList[0].@folder.toString() + "/" +  snowballList[0].@imagepath.toString();
			
				
				loadManager.add( new LoaderData( snowballName, snowballPath) ); 
				//
				snowballFightGraphicNameArray.push(snowballName);
			}
		
			
			
			var snowballFightLoaderSet:LoaderSet = new LoaderSet("snowballFightLoaderSet", 10, 									snowballFightGraphicNameArray);
}

snowballLoadSequence.push(snowballFightLoaderSet);

So that when I want to show the snowballs in the fight state, I can grab those graphics like so:

// FightState.as

	for (var snowballCounter:uint=0; snowballCounter< totalSnowballs; snowballCounter++)
			{
				var snowball:SnowballSprite = new SnowballSprite (loadManager.getLoaderByName("snowball" + snowballCounter).contentLoaderInfo.content,
																contentList.getObjectProp("snowball", "decreasehealthby"),
				);
																
																
				snowball.x = Math.floor(Math.random() * 400 - 100);
				snowball.y = Math.floor(Math.random() * 100);
							
				snowball.alpha = 0;
		
				snowball.vx = Math.random() * 20 - 1;
				snowball.vy = Math.random() * 20 - 1;
				
				snowballArray.push(snowball);
			
				fightSetupSequence.push({scope:snowballArray[snowballCounter], alpha:1, time:1, transition:"linear"} );
			}

Author:Brandon Flowers



Sign in to add a comment
Powered by Google Project Hosting