Published: 29 Dec 2009
By: Xianzhong Zhu
Download Sample Code

In this article, we will focus upon the development of the front end of the game using the MVP pattern; in the second part, we will discuss the database related work using the MVVM pattern.

Contents [hide]

The WaspKiller Game with Silverlight 3, .NET RIA Services, MVP and MVVM Patterns Series

  • Part 1 In this article, we will focus upon the development of the front end of the game using the MVP pattern; in the second part, we will discuss the database related work using the MVVM pattern.
  • Part 2 In this second part, we will continue to discuss the WaspKiller game development - to extend the functionalities with the server-side database support. As mentioned in the first part, we're going to rest upon another well- known design pattern, MVVM, to achieve the extension, and at the same time, introduce Microsoft .NET RIA Services framework to smooth out the whole architecture design.
  • Introduction

    Recently, Microsoft Silverlight technique has become more and more heated both in the group of professional developers and amateurish programmers. As far as Silverlight is concerned, people cannot help comparing it with Adobe Flash. In this article, we are not going to dwell upon the pros and cons of the two techniques. As we know, however, Microsoft has brought out a better search engine-friendly declarative language into Silverlight, i.e. XAML.

    Using XAML, developers can easily create hundreds of lines of declarative markups within several minutes. Nevertheless, whether to create practical enterprise data-oriented applications or online games with server-side database support, with the scale getting larger and larger, what design pattern to rest on becomes a more and more severe and complex problem.

    Up until now, several design patterns emerged to boost the application development, such as MVC, MVP, and the latest MVVP. Surely you have read the stories concerning the three patterns either from the various forums or in personal blogs. As far as I know, however, how to make the most effective use of these tools is still a puzzled decision. This is the main reason for writing this series of articles.

    In my opinion, in developing large server-side data-driven online games, we'd better fall back on the MVP pattern to organize the front-end related components due to various kinds of controls, assets, and tons of XAML code mixed together. When developing the server-side data-related components, we can resort to the MVVP pattern to modulate them, and thus reduce the coupling between these components to the greatest degree. Moreover, with .NET RIA Services framework coming to help, it becomes even easier to accomplish this target.

    In this two-part series, we will construct a simple Silverlight shooting game named WaspKiller using all the above tools to prove my points. In this first part, we will develop the front end of the game using the MVP pattern.

    NOTE

    The development environments we'll use in the sample application are:

    Windows XP Professional (SP3);

    .NET 3.5 (SP1);

    Visual Studio 2008 Professional (SP1);

    Microsoft Expression Blend 3;

    Microsoft Silverlight Tools for Visual Studio 2008 SP1;

    .Net RIA Services July 2009 Preview;

    SQL Server 2008.

    Introducing the MVP Pattern

    Derived from the famous MVC pattern, the MVP pattern is also an OOP pattern, which aims to separate the user interface (the view) from the business logic (the model). The pattern separates the responsibilities across the three typical components, resulting in each one having only one responsibility.

    • The view: responsible for rendering the UI elements.
    • The model: responsible for business behaviors and state management.
    • The presenter: responsible for interacting between the view and the model.
    Note

    In real cases, people usually create view interfaces first to loosely couple the presenter from its views. And also, the model interfaces are created before the models to achieve a similar purpose as with the view case.

    To gain a better understanding of the MVP pattern, Figure 1 illustrates the general logical view of the MVP pattern.

    Figure 1: A bird's-eye view of the MVP pattern

    A bird's-eye view of the MVP pattern

    As shown in Figure 1, the user interacts with the user interface. One makes an action which results in the view firing events. It's the presenter's duty to handle all these and update the model accordingly. On the other hand, when the model is modified, the view also has to be updated to reflect the changes.

    At the moment we leverage the key benefits of the MVP, such as loose coupling, clear separation of responsibilities, code reuse, flexibility and extendibility, we should also be aware of the key drawbacks, such as additional complexity and event driven programming. Therefore, the MVP pattern is not recommended to develop small applications.

    For now, readers should make clear we are going to leverage two kinds of design patterns to solve related problems. In this first part, we will use the MVP pattern to figure out the wasp data related things, while the MVVM pattern will be utilized to tackle the player score related stuffs.

    Next, let's run to the question in our game- the wasp related pattern design.

    The Wasp Data-related Pattern Design

    In the WaspKiller game case, the MVP pattern is mainly associated with the components contained in Figure 2 below.

    Figure 2: The MVP design architecture mainly-related components in the WaspKiller game

    The MVP design architecture mainly-related components in the WaspKiller game

    We define related interfaces for the model and the view to inherit from. Since the model and the view both derive from the corresponding interfaces, by holding these interfaces the presenter can control both the model and the view. For facilitating the communication between the model and the view the two components define the related events in the related interfaces. However, all the data management between them is achieved through the presenter.

    As you see from the figure above, all the components only relate to the wasp. The wasp, as you'll find in the game, plays the main role. They fly and buzz from left to right along special path, challenging its rival (the player). The player can shoot at the wasps. If he hits the wasp, the wasp will disappear and the game score and level will be increased accordingly. If the player misses the wasp, it will continue to buzz singing a triumphant song and fly away from the screen. How to deal with all these requirements in an efficient way? Maybe the MVP pattern can help, as described in Figure 2. Let's see what happens.

    Designing the Model Interface

    The IWaspModel is the interface for the wasp model. Usually the MVP pattern it's recommended to design an interface for the model, and the model should implement no other interfaces. Apparently, writing the interface first instead of writing the class will bring out many benefits, such as more easier-to-understand communication between classes, better expansion, reusability, scalability, and looser coupling. The complete source code of the interface IWaspModel is given in Listing 1.

    Listing 1: Definition of the interface IWaspModel

    In the above interface, three methods are declared which are used to manipulate the start, stop and score of the wasp model. The subsequent event is used by the presenter to implement the communication between the wasp view and the model. When the wasp model changes the WaspChanging event will be triggered, and in the corresponding event hander the wasp view will be updated. Also, we used a custom event argument class WaspEventArgs; you can refer to the source code for the details.

    Next, let's look at the wasp model design.

    Designing the Model

    In this WaspKiller game, the wasp plays the main role especially as far as the front-end data is concerned. Therefore, we should define a group of properties to provide services for it. Listing 2 shows the complete code of the wasp model.

    Listing 2: The wasp model definition

    We've provided the following functionalities in the wasp model:

    • A DispatcherTimer control, used to change the position of the wasp.
    • An instance of the custom class SineWave, used to define the flying path of the wasp.
    • A helper method InitData is defined and called in the method Start, which is used to make the necessary initialization, i.e. to create the instances of the custom class SineWave (used to specify the flying path) and WaspEventArgs (used to specify the coordinates info).
    • In implementing the method Score of the interface IWaspModel, the C# lock mechanism is used to ensure modifying the score and level data will succeed.
    • A protected and virtual method OnWaspChanging is defined, which is used internally to trigger the WaspChanging event.
    • When the Tick event is fired, the instance of the class WaspEventArgs is populated with related coordinate info and passed as the event parameter into the event invoking method WaspChanging.

    Later on, you will notice that when the WaspChanging event is triggered in the presenter, the Wasp view will be updated using the data passed through the above custom event parameter.

    Next, let's look at the Wasp view related design.

    Designing the Wasp View

    As with the case of the model, here we defined a view interface to loosely couple the presenter from its view. The complete code of the interface IWaspView is shown in Listing 3 below.

    Listing 3: The IWaspView interface definition

    As shown above, this interface contains only one method which responsibility is to update the Wasp view. In our implementation of the MVP pattern, it is the responsibility of the presenter to update the Wasp view. Moreover, as you see, three events are exposed, which will play important roles in the Wasp view operations.

    As far as the Wasp view is concerned, Microsoft Expression Blend 3 helps a lot. To draw the wings, body and mouth of the wasp you will spend plenty of time by manual XAML coding. With Expression Blend 3 coming to help, however, you will finish a sketch of the wasp in a few minutes. As you may have doped out, making the wings flip will have to use the Storyboard element. But all this is simple.

    For brevity, we are not going to list the Wasp view related XAML code, but we'll leave space to the code-behind explanations.

    Listing 4: The code-behind definition of the Wasp view

    The code-behind is also simple as supposed. However, there are still several points worth noticing:

    • When the wasp is hit the MouseLeftButtonDown event handler of the wasp is fired. If the animation (the wasp is flying) is going on, start another animation named aniDisappear to hide the wasp and the Score event will be triggered by calling the method OnScore.
    • The method InitPosition is used to initialize the position of the wasp. As you see, the initial position of each wasp in the game is at the far left side outside the screen.
    • The method Update is used to update the position of the wasp.
    • The three events, Start, Score, and Stop, are derived from the IWaspView interface. These events' related event handlers will be attached by the presenter and further trigger the other three corresponding events, Start, Score, and Stop, of the wasp model.

    Next, let's look into how the presenter connects the wasp model with the wasp view.

    Designing the Presenter

    In the MVP pattern, the responsibility of the presenter, as the role of Controller in the MVC pattern, is to act as a mediator between the view and the model. Listing 5 indicates the complete definition of the presenter class.

    Listing 5: The complete definition of the presenter

    Note that he presenter owns references to the view and the model. On the one hand, if the view triggers related events, the presenter will call the corresponding methods of the model and present the results to the view; on the other hand, if the event WaspChanging is fired on the model, the presenter will handle the event and invoke the method Update of the view to update the view.

    With the basic components related to the MVP pattern ready, we can explore the detailed implementation of other aspects of the application.

    Designing the UserControls

    As a typical Silverlight game application, there are usually a couple of tiny UserControls around the main topic. In this case, we've utilized the following UserControls:

    • Cloud (Cloud.xaml), a set of XAML markups produced with Expression Blend 3, which is used to simulate the cloud in the real environment.
    • Flower (Flower.xaml), a set of XAML markups produced with Expression Blend 3, which is used to simulate the flowers in the meadow.
    • Tree (Tree.xaml), a set of XAML markups produced with Expression Blend 3, which is used to simulate the trees in the background environment.
    • Background (Background.xaml), which is the parent container to hold the variations of the Cloud UserControl, Tree UserControl, Flower UserControl, etc. to form the background of the game.
    • Gun (Gun.xaml), which is used to draw the collimator used to kill the wasp. To achieve a more vivid effect, we change the ScaleTransform related properties when and after the fire in its two methods, i.e. Fire, and Reset, respectively.
    • Sound (Sound.xaml), which is used to control the background music and gun fire sound together.
    • MyTimer (MyTimer.xaml), which is in fact a wrapper of the DispatcherTimer control, as well as extending it with methods and events. The MyTimer is used to control the whole time of
    • Game tip board (GameTip.xaml), which is used to prompt the player start or restart the game, also with an event to extend the function.

    For simplicity, we leave out the detailed discussion about the above listed UserControls. For the details, you can download the source code.

    Note

    Since we can use Expression Blend 3 to transform a special asset composed of a set of XAML markup into a UserControl, we only need to create one such UserControl. Then, we can duplicate the UserControl many times and recur to various kinds of transformations to change the related asset.

    Next, let's say a few words about a singleton helper class in this game.

    A Singleton Helper Class

    To effectively control the game score and level increment or decrement (sorry for not supporting this functionality) only under special conditions, we've designed two related classes, Scorer to hold the current score, and Singleton to insure there is only one instance of the class Scorer during the game.

    First, let's take a look at the data-aware class Scorer, as shown in Listing 6.

    Since we've used the data binding way to show the game score and level in the main view of the game, it's not strange to let the class Scorer inherit from the interface INotifyPropertyChanged. In a word, the class Scorer simply acts as a data wrapper of the game score and level data.

    Then, we designed a class Singleton to help to ensure that there is only one instance of the class Scorer. Listing 7 provides the source code of the class Singleton.

    Listing 6: The singleton class definition

    First, please note that the new constraint requires that the generic parameter should have a non-parameter constructor. For more about the usage of the where and new constraints, readers can refer to the related help in MSDN.

    Next, we have defined a public and static read-only property Instance, through which we return the internal, static, and readonly property instance (of type T) which is an instance of class T.

    OK, now by defining the above generic class Singleton<T>, we can access its only and static property Instance of type T, and consequently ensure that the generic parameter (the class Scorer) has only one instance.

    In the next section, we'll start to look at the main view of the game.

    Designing the Main View of the Game

    The main view of the game is accomplished through view- MainPage.xaml. Figure 3 below illustrates one of the running-time snapshots of the WaspKiller game.

    Figure 3: One of the running-time snapshots of the game

    One of the running-time snapshots of the game

    As seen from the figure, to create a more lifelike scene, many Silverlight UserControls are used. Wasps are generated with the control of another timer control, flying from left to right. Within one minute (the maximum game duration) the player can fire to the wasps to gain score and advance to a higher level. During the game, the player can click the button at the top right to see the current score board (to be discussed in the second article).

    Designing the XAML Code

    With a couple of custom UserControls defined above, there is not much XAML code in the file MainPage.xaml. Let's first research into the first part as shown in Listing 8.

    Listing 7: XAML code to define the background, sound and game title bar

    There is nothing peculiar in the above XAML code. We simply created the instances of the Background and Sound classes in declarative code. Then in the StackPanel element named panelScorer we embedded a custom timer control MyTimer (used to control the total time of the game), and at the same time, used the data binding solution to display the game score and level info. Next, we used the Button control named btnFullScreen to toggle between normal and full screen modes. Later on, we defined a Canvas control named CanvasHighscores used to open a ChildWindow control to show all the players score and related data.

    Let's continue to delve into the following XAML code, listed below.

    Listing 8: XAML code to define the wasp-generating container, game tip and gun

    Here, we simply place XAML code to create the wasp-generating container, game tip board and gun controls. For more related stories, let's continue to examine the code-behind.

    Behind the Scenes

    Now, let's take a look at the code-behind file, MainPage.xaml.cs, to see what really happens behind the scenes.

    Thanks to the modular design, there is not too much code. Let's first see the local variable definitions.

    To control the mouse cursor shape more efficiently, we defined the Boolean variable mode. When the value is set to false, we forbid the player to start the game. The subsequent DispatcherTimer control variable timer is used to control the states of the wasps. When the time interval ticks, one wasp will be activated and fly out. The third variable waspList is used to hold all the Wasp control instances. The fourth variable waspIndex refers to the current wasp.

    Next, let's look at the important event handler MainPage_Loaded, as shown in Listing 10.

    Listing 9: Code for function MainPage_Loaded

    Here, we only want to stress two points. One is that we used a for loop to generate 32 wasps to hide in the wasp container control (and also stored into the collection variable waspList). Of special importance is herein we used the Presenter WaspPresenter with which to bind the model waspModel and view Wasp together. Again relating to the above-discussed MVP pattern, you may gain a much clearer view of the inner workings between related components. The other point is that we bind the score related data to the control panelScorer with the help of the following line of code:

    Finally, let's look at the Start event when the game tip board is clicked.

    Listing 10: Code for the event handler gameTip_Start

    First, in the foreach loop, we stopped all the wasps. Then, we made the necessary initialization. Last, by triggering the Start event of the two timer controls, we startted the game. That's all.

    Until now, all the crucial code in developing the WaspKiller game has been covered. For other details, please see the source code provided.

    Summary

    In this first part of the game application, we've focused upon the use of the MVP design pattern, with which we have accomplished the majority of the front end programming. Due to various reasons, what I brought to you is only a rough and even ugly game. So, there are many aspects that need to be improved. On the other hand, real-world games often relate to back-end databases. For this reason, we are going to leverage another famous pattern, MVVP, to accomplish the back-end database related development in the second part of the series.

    The WaspKiller Game with Silverlight 3, .NET RIA Services, MVP and MVVM Patterns Series

  • Part 1 In this article, we will focus upon the development of the front end of the game using the MVP pattern; in the second part, we will discuss the database related work using the MVVM pattern.
  • Part 2 In this second part, we will continue to discuss the WaspKiller game development - to extend the functionalities with the server-side database support. As mentioned in the first part, we're going to rest upon another well- known design pattern, MVVM, to achieve the extension, and at the same time, introduce Microsoft .NET RIA Services framework to smooth out the whole architecture design.
  • <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Xianzhong Zhu

    I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...

    This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    Displaying Notification Messages in a Silverlight Dashboard Application
    In this article we will see how we could display a notification message and further a list of notifi...
    Air Space Issue in Web Browser Control in Silverlight
    Air Space issue is a common issue in Web Browser control in Silverlight and WPF. To explain the issu...
    TextBox Row Filter in Telerik's RadGridView in Silverlight
    If you have come across the JQGrid features, you might have seen the filter row available as the fir...
    Widget Refresh Timer in MVVM in Silverlight
    In this article we'll see how to refresh and disable widgets using the Model View View-Model pattern...
    Develop a Flexible 2.5D Scene Editor Targeting Silverlight RPG Games - Part 2
    In this article, I'm going to introduce to you how to construct such a 2.5D RPG game scene editor th...
    Top
     
     
     

    Discussion


    Subject Author Date
    placeholder Won't compile Dave Secret 6/29/2010 2:02 PM
    About .NET RIA Services vs WCF RIA Services Xianzhong Zhu 6/30/2010 8:26 AM

    Please login to rate or to leave a comment.