Wednesday, January 12, 2011

Implementing MVC Architecture in AS3

MVC stands for Model View Controller. Each of these is an important component for any game development. Their roles are explained as follows:

1.Model: It manages the behavior of any application. It tells how the complete data is structured. It responds to any request made about the game state, mostly by the view.
2.View: It is the display of the information or data to the user.
3.Controller: It interprets the inputs from the user, informs the model to change it, making the view to display the changes accordingly.

In short, the Controller interprets the input, processes it in the Model, and gives the output to the View.


                                                  Input --> Processing --> Output
                                                  Controller --> Model --> View





Take an simple example of a calculator. Calculator is an electronic device that we use in our day to day life. Suppose we want to perform addition operation of 2 numbers. Let us see how the MVC architecture applies here.

First Number Input --> Press the number key of the View --> Input goes to the controller --> controller updates it in model --> the pressed number key is displayed by the view
Operation Input --> Press the "+" key of the View --> Input captured by the controller --> controller updates the model
Second Number Input --> Press the number key of the View --> Input goes to the controller, addition operation is performed --> controller updates the second input and the final output in the model --> the pressed number key is displayed by the view
Result --> Press the "=" key of the View --> Input captured by the controller --> view displays the result as stored in the model

With an MVC architecture, it becomes very easy to write the code in an organized way, and it can then be easily understood by the others as well.

Using MVC in AS3 programming.
Again taking a simple example, capturing data on pressing the keys from the keyboard and priting it in view.

Model will store the data (pressed key) and will be used to retrieve the same.
Hence this will have 2 functions (setter and getter). Model Interface, IModel.as, is written as follows:
package
{
         import flash.events.*;
         public interface IModel
        {
                  function setKeyId(key:uint):void
                  function getKeyId( ):uint
         }
}

The Model.as file becomes:

package
{
         import flash.events.*;
         public class Model implements IModel
        {
                 private var lastKeyId:uint = 0;
                 public function setKeyId(key:uint):void
                {
                         this.lastKeyId = key;
                         dispatchEvent(new Event(Event.CHANGE)); // dispatch event
                }

                 public function getKeyId( ):uint
                {
                         return lastKeyId;
                }
        }
}

All the keyboard events are handled in the Controller. Controller Interface will have just one function to capture the keyboard event:

package
{
         import flash.events.*;
         public interface IController
        {
                  function keyPressHandler(event:KeyboardEvent):void
        }
}

The Controller.as files implements the IController interface:

package
{
         import flash.events.*;
         public class Controller implements IController
        {
                  private var model:IModel;
                  public function Controller(aModel:IModel)
                  {
                             this.model = aModel;
                  }
                 
                 public function keyPressHandler(event:KeyboardEvent):void
                 {
                             model.setKeyId(event.charCode); // change model
                 }
        }
}

The View.as file provides the view to the user, wherein he selects the keyboard key to be pressed, and when the key is presses, View class is useful again to print the key id on the screen.

package
{
         import flash.events.*;
         import flash.display.*;

         public class View
         {
                  private var model:IModel;
                  private var controller:IController;
                  public function View(aModel:IModel, oController:IController,target:Stage)
                  {
                            this.model = aModel;
                            this.controller = oController;

                            // register to receive notifications from the model
                            model.addEventListener(Event.CHANGE, this.update);

                            // register to receive key press notifications from the stage
                            target.addEventListener(KeyboardEvent.KEY_DOWN, this.onKeyPress);

                   }

                  private function update(event:Event):void
                  {
                           // get data from model and update view
                           trace(model.getKeyId( ));
                  }

                  private function onKeyPress(event:KeyboardEvent):void
                  {
                          // delegate to the controller (strategy) to handle it
                          controller.keyPressHandler(event);
                   }
          }
}

And finally, the MainClass.as, where all the class instance are created is :

package
{
         import flash.display.*;
         import flash.events.*;
         public class Main extends Sprite
         {
                  public function Main( )
                  {
                           var model:IModel = new Model( );
                           var controller:IController = new Controller(model);
                           var view:View = new View(model, controller, this.stage);
                  }
         }
}

Let us examine how this complete MVC program work.

MainClass.as class creates the instances of the model, view and the controller classes, which implement the functions of their respective interfaces. The keyboard keys are in the user's view. So, if any key is presses, the event is captured in view and handled in the controller class. The controller updates the model about the key pressed. After which the model dispatches CHANGE event, which signifies that keyboard captured value has been changed (with respect to the previous pressed key value). This event is handled in the view and the keyboard value is displayed to the user on his screen.

References: http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/actionscript/pdfs/ora_as3_design_patterns_ch12.pdf

No comments:

Post a Comment