[AS3] StateView

StateView by thienhaflash (thienhaflash@gmail.com)
Updated			: 26.Feb.2012
Callbacks 		: -
Features 		: 
	Automatically get the children of a container use as states
	Support optional custom transitions when changing states
	Support optional callbacks on each child to be called when transition start / end
		(onStartIn, onStartOut, onEndIn, onEndOut)
	Automatically disable interaction and block state changes while doing transition
	Fully trace for invalid operations for easy tracking down
	No dependencies (don't even need a tween engine)

While doing minigames and websites, I see that there are a need for some kind of container that contains only one child at a time. Think of the games as many screen, you can only see one screen at a time (Menu, Introduction, Help, Highscore, GamePlay, Profile, Result …) which an optional of popups overlays (Loading, Pause, Login, Alert…), taking care of transitioning between states might need some of your work, firstly you need a variable to save the current main content another variable to save overlay content, then once you need to change the content you will do the check and making transition out for current content, wait until it completes and do the transition in … well, It’s not hard at all but surely it will take your time and it’s much more complex for the code when there are not two but four or five layers like that. And using StateView should be the general solution for this problem.

Let’s take the game above as a real use case for StateView. We will need two stateViews, one for main game scenes, one for popups. Something like this, assumes that mcMain is the Sprite that contains all game scenes (mcMenu, mcIntroduction, mcHelp, mcHighscore, mcGamePlay, mcProfile, mcResult) and mcPopup is the Sprite that contains all the popups used in the game (mcLoading, mcPause, mcLogin, mcAlert)

var _mainView : StateView = new StateView(mcMain, 'mcMenu');
var _popupView : StateView = new StateView(mcPopup);

What we’ve done is creating two StateView, set the first one _mainView to show mcMenu, and the second one to be blank (defaultState = ”)

We can then attach some callbacks to each state content (the corresponding child MovieClip) so we know when our scene comes to active to update the content. For the sake of simplicity, we consider all children of mcMain are MovieClips that we can attach whatever kind of properties we want to it and take mcIntroduction to investigate this time : We want the texts to reset when the page start to make the transition in and then it will scroll up (like movie credits) when the transition is done, we also want to stop this automatic scroll as soon as the page is transitioned out.

var mcIntroduction : MovieClip = _mainView.getStateContent(); //a bit show off, sure, you can call getChildByName from mcMain

mcIntroduction.onStartIn = function (): void {
//do reset text position here, don't start the scrolling timer yet

mcIntroduction.onEndIn = function (): void {
//ok, start the scrolling timer now

mcIntroduction.onEndOut = function (): void {
//completely out, stop the scrolling timer now

You might want to tweak up the transitions for each View, for example you might want to have Fade for _mainView but needs a slide for _popupView, in that case, a simple tween function will do the trick

_mainView.tweenFunc = function (inObj: Object, outObj: Object, onComplete: Function){
//inObj might happens to be null if we are transitioning to an empty state (no popups' case), so make sure you checked it
if (inObj) ;//do transition in for inObj
if (outObj) ;//do transition out for outObj
//make sure that you calls onComplete when the transitioning is done, if the animation is complex and it's difficult to attach an onComplete correctly, a setTimeout might do the trick !

The above approach is suitable for guys who wants to separate the assets completely from the code (with some name conventions of course). If you choose to have linkage MovieClips and using a class for each scene, you still has necessary flexible by optionally declare onStartIn, onEndIn, onStartOut, onEndOut when you need (no strictly binded interfaces to be implemented).

One of the limits of StateView is that it requires the scene contents to be available at declaring time, which make it only suitable for small games / apps. I’m looking ahead to add on-demand loading for scenes, but that might bloat the class someway and we’d better think about it carefully. I’m also thinking about adding event model for this together will global callbacks but not really sure about how useful it is. And that’s it for now, just that SIMPLE !

So happy flashing, everyone !


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s