Thursday, February 14, 2013

Firefly Part 2: Basic game flow with ViewNavigator

In our previous post we have created and set up project for game "Zombie: Rising Up". Now we need to make game navigation that you can accomplish by using ViewNavigator manager. This manager has ability to switch between views and load necessary textures. It also can plays different transition such as animated effect, shows loading indicator or advertisement while textures are loading. ViewNavigator reacts on activation/deactivation and lost context events loading dropped textures and showing special loading indicator.

URL for downloading showcase project is provided at the bottom of this post, you can download it and import as project into your FlashBuilder IDE. So now, it's time to add into our game main view that will be like container for other views and hold view navigator. The best place to add it - handler for Starling initialize event.
/** 
 * Starling initialized event handler.
 * Place for textures and model registration, fonts loading.
 */
protected function starlingInitializedHandler(event:StarlingEvent):void
{
  setMainView(new MainView());
}
Our game will have following view states:
  • Menu view
  • Credits view
  • Game view
  • Score view
  • Pause popup view
  • Exit popup view
For now lets create blank views for all the states listed above. Then place into each constructor text label that will indicates view's name:
public class CreditsView extends Sprite (
{
  public function CreditsView()
  {
    super();
    var label:TextField = new TextField("Credits", "Chango", 40);
    label.setActualSize(300, 100);
    addElement(label);
  }
}
Now we need to register all these views into our view navigator, so in MainView we need to add following:
public function MainView()
{
  super();

  // Initialize game view navigator
  navigator = new ViewNavigator(this);

  // Add views and pop-ups within game view navigator
  navigator.addView(MenuView, ViewStates.MENU); 
  navigator.addView(CreditsView, ViewStates.CREDITS);
  navigator.addView(GameView, ViewStates.GAME);
  navigator.addView(ScoreView, ViewStates.SCORE);
  navigator.addPopUpView(PausePopUpView, ViewStates.PAUSE);
  navigator.addPopUpView(ExitPopUpView, ViewStates.EXIT);

  // Initialize additional game states
  navigator.hibernateView = new LoadingView();
  navigator.lostContextView = new LostContextView();
  // Menu transitions
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.MENU, ViewStates.CREDITS));
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.MENU, ViewStates.GAME));

  // Credits transitions
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.CREDITS, ViewStates.MENU));

  // Game transitions
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.GAME, ViewStates.MENU));
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.GAME, ViewStates.SCORE));
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.GAME, ViewStates.GAME));

  // Score transitions
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.SCORE, ViewStates.GAME));
  navigator.addTransition(new BasicTransition(ViewStateEvent.SWITCH_TO_STATE, ViewStates.SCORE, ViewStates.MENU));

  // Back device button (Android only), open popup, deactivate transitions
  navigator.addTransition(new BasicTransition(ViewStateEvent.BACK, ViewStates.CREDITS, ViewStates.MENU));
  navigator.addTransition(new BasicTransition(ViewStateEvent.BACK, ViewStates.SCORE, ViewStates.MENU));

  navigator.addTransition(new PopUpTransition(ViewStateEvent.OPEN_POPUP, ViewStates.MENU, ViewStates.EXIT));
  navigator.addTransition(new PopUpTransition(ViewStateEvent.BACK, ViewStates.MENU, ViewStates.EXIT));
  navigator.addTransition(new BasicTransition(ViewStateEvent.DEACTIVATE, ViewStates.GAME, ViewStates.PAUSE));
  navigator.addTransition(new BasicTransition(ViewStateEvent.BACK, ViewStates.GAME, ViewStates.PAUSE));
}
On added to stage handler lets switch to default view which is of course menu view:
private function addedToStageHandler():void
{
  dispatchEvent(new ViewStateEvent(ViewStateEvent.SWITCH_TO_STATE, ViewStates.MENU));
}
Lets add buttons "Play" and "Credits" on Menu view. Use for it text fields instead of real buttons because at the moment we don't have any textures jet  (we will replace them later in next posts)
private var play:TextField;
private var credits:TextField;

public function MenuView()
{
  super();
  var label:TextField = new TextField("Menu", "Chango", 40);
  label.setActualSize(300, 100);
  addElement(label);

  play = new TextField("Play", "Chango", 40);
  play.setActualSize(300, 50);
  play.setActualPosition(100, 100);
  addElement(play);
  play.addEventListener(TouchEvent.TOUCH, gameTouchHandler);

  credits = new TextField("Credits", "Chango", 40);
  credits.setActualSize(300, 50);
  credits.setActualPosition(100, 150);
  addElement(credits);
  credits.addEventListener(TouchEvent.TOUCH, creditsTouchHandler);
}

private function gameTouchHandler(e:TouchEvent):void
{
  var touch:Touch = e.getTouch(play);
  if(touch && touch.phase == TouchPhase.BEGAN)
    dispatchEvent(new ViewStateEvent(ViewStateEvent.SWITCH_TO_STATE, 
                                     ViewStates.GAME));
}
  
private function creditsTouchHandler(e:TouchEvent):void
{
  var touch:Touch = e.getTouch(credits);
  if(touch && touch.phase == TouchPhase.BEGAN)
    dispatchEvent(new ViewStateEvent(ViewStateEvent.SWITCH_TO_STATE, 
                                     ViewStates.CREDITS));
}
So know we have following navigation schema:
1. On menu view we have two buttons - "Play" and "Credits":
  • Play button leads you to Game View.
  • Credits button navigates you to Credits view.
  • Android back button goes to Exit Popup.
2. On Credits view: 
  • Android back button goes to Menu view.
  • Deactivate/activate leads you to Menu view.
3. On Game view: 
  • Android back button goes to Pause view.
  • Deactivate/activate leads you to Pause view.
  • Score button navigates to Score view.
4. On Pause view:
  • Android back button goes to Game view.
  • Tap on popup goes back to Game view.
5. On Score view Android back button goes to Game view.
6. On Exit Popup Android back button goes to Menu view.

Showcase project source: ZombieRisingUp Part 2

6 comments:

  1. Really nice :) But where connections with Android back button are specified? View changes did not clarify directions as i see... how sdk detects what change is needed exactly?

    ReplyDelete
  2. Sorry, didn`t noticed ViewStateEvent.BACK / ViewStateEvent.DEACTIVATE
    Now its clear :)
    ---
    i just starting new game with Firefly SDK

    ReplyDelete
    Replies
    1. This is great. Feel free to contact us in case of any questions or comments. Please refer https://github.com/in4ray/firefly-sdk/issues in case of any issues.

      Delete
  3. I try to use your template with FlashDevelop but I can't because you use .fxg and FlashDevelop don`t recognize these files. Do you know a simple workaround or I must change the whole project? (Sorry for my English)

    ReplyDelete
  4. Hi,

    I tried to use your framework but i encountered problem. I have two button, left button is to move and the right button is to fire but don't work if do the same time. Please help, thanks

    ReplyDelete
  5. Aha, I knew it was that scene! I really liked how Flash was starting to think about a place called home there.
    appvn

    ReplyDelete