Published: 23 Sep 2011
By: Xianzhong Zhu
Download Sample Code

In this last article, we are going to continue to research into the easy and difficult aspects in creating the Silverlight based game, with an eye to the Android platform based version.

Contents [hide]

The Migrating PushGame from Android to Windows Phone 7 Series

  • Part 1 Is it possible for us to migrate tons of existing Android based games to Windows Phone 7? If so, how can we do that? This series of articles tries to answer this question via the popular Sokoban (for readers to more easily understand, we will use the term 'PushBox' later on) game (an ancient puzzle game from Japan).
  • Part 2 Starting from this article, we'll delve into the real and interesting stuffs in developing the PushBox game - the welcome view and the menu view related design.
  • Part 3 Starting from this article, we'll delve into the key part of the PushBox game - the main interface and the core data structure in composing the game.
  • Part 4 The first three parts of this series have introduced to you the PushBox game based upon the popular Google Android platform. Starting from this article, we are going to develop the second version of the PushBox game based on Microsoft Silverlight for Windows Phone 7. Since you have gained a whole idea of the main functionalities, our attention will focus upon the similarities as well as the big differences between the two platforms.
  • Part 5 Starting from this article, we are going to introduce the key techniques of writing the Silverlight for Windows Phone 7 based game.
  • Part 6 In this last article, we are going to continue to research into the easy and difficult aspects in creating the Silverlight based game, with an eye to the Android platform based version.
  • Introduction

    In the previous article, you've learned the main modules composed of the Silverlight for Windows Phone 7 game and the switches between them. And then, you learned the important initialization method InitForGameView, which represents a typical mode to construct most Silverlight for Windows Phone 7 platform based games. In this last article, we are going to continue to research into the easy and difficult aspects in creating the Silverlight based game, with an eye to the Android platform based version.

    NOTE

    The sample development environments in the Silverlight for Windows Phone 7 version involve:

    1. Windows 7;

    2. .NET 4.0;

    3. Silverlight for Windows Phone 7;

    4. Microsoft Expression Blend 4 for Windows Phone 7 (included in item 3).

    Game Loop Control

    Up till now, as far as the stuffs for Silverlight based game applications loop control is concerned, most of them use the DispatcherTimer class directly or indirectly. Although some people choose to use Storyboard as the game loop controller, it behind the scene also depends upon DispatcherTimer. Well, now let's look at how DispatcherTimer helps to control the loop of our PushBox game. Although this sample only provides two game levels you can easily extend our design to support any number of levels.

    Now, let me give detailed explanation about the above code. The first thing is again about sound play. There are several approaches in this regard. To gain a more reusable result, I use a user control (see the file Sound.xaml) to control the sound/music playing. Now, I've put the following XAML code in the PushBox.xaml file.

    As is repeatedly mentioned, Silverlight for Windows Phone 7 does not allow putting more than one MediaElement in a page, and so is the case with this user control encapsulated one. Purposefully, I've not utilized the XNA provided SoundEffect class to play the two pieces of music synchronously. Hence, in the sample you will find only the background music can be played while the pushing box sound cannot be heard. To put the two stuffs here is just to lay emphasis upon this shortage in the Silverlight version.

    Next, if the player wins the game (with the variable status equal to 1) we should do several things. First, we stop the game controller timer. Then, we pop up the game win panel. Third, set the value of the variable selectMap (if 0 it means the current level is 1, and if 1 then 2). Finally, we invoke the helper method InitForGameView and return. Till now, I believe all these can be understood; we are not to waste time upon them. But there is a variable named bInMiddlePhaseForLevel1 still not to be explained. In fact, this variable helps to judge the situation of some box pushed into the blind area for level 1. During the course of the game, if there is a box pushed into the blind area we can easily find this and then pop up a game over (failure) dialog. However, the difficult thing lies in that as soon as the level 1 is passed there is maybe some box just pushed into the blind area (just the target place). To distinguish this from the game middle case, we introduced the bInMiddlePhaseForLevel1 variable. So, if readers are interested in showing the blind areas for level 2 you are sure to also meet such a situation.

    Well, till now, the subsequent if statement is much easier for you to follow up. If the current level is 1 and there is a box pushed into the blind area and the above mark variable bInMiddlePhaseForLevel1 is true, then we pop up the game over (failure) dialog, and then restart the game. That's all for the game loop control with DispatcherTimer!

    Next, let's focus upon another knot – how to move the sprite (porter) and box?

    How to Move the Sprite (Porter) and Box?

    As is mentioned previously, to move the sprite and box in Silverlight is not as easy as in the Android platform case. Considering all the possible input equipment supported by Windows Phone 7, I decide to use left mouse click to move them. Note the left mouse click in Silverlight for Windows Phone 7 just corresponds to a simple finger tap. And, of course, even Windows Phone 7 supports input equipments with four arrow buttons, we cannot take this as a universal case.

    Let's first look at the outlined code of the MouseLeftButtonDown event handler since it's so long.

    First, the variable typeFlag is used to identify the animation type. If the value is true it means the animation will draw the walking porter; if the value is false it means the animation will draw the pushing box gesture.

    Next, the method GetTapDirection is important, which is used to identify the click direction.

    In the above code, we first use a switch statement to obtain all the elements (via a List<UIElement> data structure) at the clicked point. Obviously, we have to distinguish between different types of game levels. Next, we are only interested in the polygons at the specified point. After grabbing the target polygon we deal with the Tag info to abstract the current sprite position info. By comparing the i and j properties of the sprite with the values hidden in the Tag property, we can easily obtain the clicking direction. To understand the above code, refer to the following definition.

    If the player does not click the corresponding areas the function returns KEY_NONE.

    Now, let's return to the method LayoutRoot_MouseLeftButtonDown. In the switch statement, according to the clicked position we modify the map structure. This is the very important part in the whole game! Readers can refer to data defined in the file MapList.cs to try to make clear the meaning of the code within the switch statement. The last part of the method LayoutRoot_MouseLeftButtonDown is around the multi-threading programming.

    Before introducing the multi-threading techniques, let's first look at the sprite definition in order to better understand the multi-threading solutions later on.

    Define the MySprite Class

    To be honest, in this sample game application, I did not cost a great effort to design the sprite class. For, all the ideas in this series are just for your reference. In our case, we defined the porter (i.e. the porter) as a Silverlight user control.

    On the whole, the user control usage related manipulation is quite the same as that in common Silverlight. Herein, we use the two public properties i and j to remember the sprite game position. And at the same time, we specify the initial value for the two properties. Next, we define a BitmapImage typed property to man to represent the current image of the sprite. Then, we define several BitmapImage arrays to hold the sprite animation related pictures. For now, we define only a method member InitializeBitmap to specify all the image data for the later used various kinds of animations. In a word, the sprite definition is easy to understand.

    As for the sprite related XAML definition, let's list them all.

    OK, there is only one point left to say about the preceding method LayoutRoot_MouseLeftButtonDown, Which is relevant to two global variables - PrevMousePosition and CurrentMousePosition.

    We use the two variables to remember the two continuous mouse clicks (finger taps) related positions. That's it.

    Multiple Threading Programming in Silverlight for Windows Phone 7

    To fully understand the logics in this section, let's list the key statements below again.

    First, the two global variables tempi and tempj are rather important- we use them to remember the currently moved box related position (the game coordinate system). In this case, the statement tempi == -1 means the sprite currently does not push the box, and then it's no use moving it. If the sprite currently pushes the box (tempi != -1), then we create a special thread BoxMoveThread_Run to move the box. The reason that we decide to use the Thread solution to make the box and porter related animations is because we want to simulate the similar implementation in the Android version. In fact, you can also try resorting to Silverlight plentiful animation support to accomplish the similar effects here. Cute readers can further dig into this solution (but there are some box and sprite orientation related data having to be prepared before using Storyboard).

    The subsequent two threads, SpriteThread_Run and SpriteMoveThread_Run, are responsible to modify the sprite moving pictures and move it, respectively.

    The thread BoxMoveThread_Run

    In this section, we are going to detail into the moving box related thread code.

    The above code represents a typical Silverlight thread case. The basic idea is: first, by iterating through the map data we locate the box related data; then, we reposition the box and accordingly change its ZIndex value, as well as alter the possible color of the box.

    In detail, there are several points deserved to be discussed. First is the Dispatcher.BeginInvoke method which represents a typical usage in the Silverlight multi-thread environment. Since we are inside an independent thread and want to modify the box on the main user interface, we have to seek help to the Dispatcher.BeginInvoke method to achieve this target.

    The second point worth noticing is the static helper class MyVisualTreeHelper and the static method GetForemostBoxElement<Image>. With this method, we locate the target box in the possible complex Silverlight component tree.

    As is seen, the core part of the above code lies in the VisualTreeHelper.FindElementsInHostCoordinates method; I believe readers can make clear the above code – we are not to waster space for related explanation.

    Well, let's now return to the method BoxMoveThread_Run. Careful readers may find a problem about the Dispatcher.BeginInvoke method. He may ask: why don't you use the following code instead of the above?

    My answer is: the current Dispatcher.BeginInvoke method does not support the preceding feature – transfer data outside of the Dispatcher.BeginInvoke method! For dig out this question, I searches Internet again and again, and finally at MSDN I found a SyncInvoke with which under simple cases (I did a simple test with it) you can achieve the above target put forward above. But, in our case, I cannot. Did I miss anything or is there anything missing with SyncInvoke? Interested readers can continue to research into this question.

    Next comes another crucial technique in the Silverlight base game: how can we reposition the moving box? You may remember the previous Android based version utilized some experience data to calculate the box's position. I found this formula can no more adapt to the Silverlight case. So I use my own experience data:

    Here the two values, VerticalXforSprite and VerticalYforSprite, are both defined as global constants in the file Global.cs. However, the player can push the box around the warehouse again and again, as a result of which even the experience data may lost their effect – the box may be off the right position. So, I have to create another helper method AdjustBoxPosition to help to adjust the box to the right place.

    In the above code, the array UpperLeftCoordinatesforBoxes is also another hard-coded data for the game. As emphasized previously, this way may be bad design, but it did help to precisely adjust the box's position.

    As for changing the box related ZIndex value, I use the well-known painter algorithm. If possible, I will write another article around game map editor to again delve into this algorithm.

    At last, please pay attention to the two helper methods, ChangeBoxColorFromGreenToGray and ChangeBoxColorFromGrayToGreen, with which we can accomplish the objective of changing the grey color of a box into green, and vice versa. Also, please pay attention to the preconditions of invoking the two methods.

    The two sprite related threads

    Now that you've got a better understanding with the thread BoxMoveThread_Run, as for the rest two sprite related threads, SpriteThread_Run and SpriteMoveThread_Run, there is not much difficulty.

    First, let's take a look at the comparably simpler thread SpriteThread_Run.

    Without the first two statements, I believe, you are sure to well understand the above code. Simply put, by beforehand knowing the sprite moving direction and what kind of pictures to draw, we draw the related pictures. Again, since we are in a worker thread circumstance we use the Dispatcher.BeginInvoke method to achieve the target of changing the sprite related pictures.

    Well, what is the use of the first two statements? They are especially designed for level 1 of the game. As you've known, we designed a special button to help the players to see clearer the blind area. Without the first two statements in this thread, when there is a box pushed into the blind area and the game restarts, you will find the sprite already moves a step towards its neighboring polygon (which corresponds to the direction towards which the box is pushed into the blind area). This peculiar thing is relevant to the complexity of multi-threading programming.

    Next, let's look at another thread SpriteMoveThread_Run with which to move the sprite.

    Another long method, isn't it? But, no worry! With the two threads introduced before, there is little left deserving to be explained. The first two statements play the same role as those in the thread SpriteThread_Run. Next, with the similar idea of the thread BoxMoveThread_Run, we drew the sprite, as well as adjusted its position (via the helper method AdjustSpritePosition) via hard-coded data. Note as soon as we change the sprite's position, we modify its values of the i and j properties.

    The last lines of code are very significant in the game, with which to set the game status, as well as place the sprite to the starting position of every game level. This kind of programming is another complexity resulted from the multi-threading techniques in Silverlight.

    One last word is during you readers run the sample game you will sometimes find the sprite can enter into the box in front of him. This is the result of the multi-threading in Silverlight – I've not taken into consideration the synchronous policy yet! I found the synchronous action is very, very difficult to achieve, so I purposefully ignore it. Well, when you met the above case of sprite into the box, please again click the last position to let the sprite jump out of the box, and then continue with the game.

    Summary

    Well, another long story has ended! On the whole, it is not easy to develop the Silverlight for Windows Phone 7 based version for the PushBox game! As you've seen, although we introduced the 2.5D design we've not obtained the attractive 2.5 effect as expected! Part of the reasons may be relevant to the unsatisfactory input support in Windows Phone 7; while part of the reasons may be our failure design and development. Anyway, you've go another real experience with Silverlight for Windows Phone 7 based game design.

    The Migrating PushGame from Android to Windows Phone 7 Series

  • Part 1 Is it possible for us to migrate tons of existing Android based games to Windows Phone 7? If so, how can we do that? This series of articles tries to answer this question via the popular Sokoban (for readers to more easily understand, we will use the term 'PushBox' later on) game (an ancient puzzle game from Japan).
  • Part 2 Starting from this article, we'll delve into the real and interesting stuffs in developing the PushBox game - the welcome view and the menu view related design.
  • Part 3 Starting from this article, we'll delve into the key part of the PushBox game - the main interface and the core data structure in composing the game.
  • Part 4 The first three parts of this series have introduced to you the PushBox game based upon the popular Google Android platform. Starting from this article, we are going to develop the second version of the PushBox game based on Microsoft Silverlight for Windows Phone 7. Since you have gained a whole idea of the main functionalities, our attention will focus upon the similarities as well as the big differences between the two platforms.
  • Part 5 Starting from this article, we are going to introduce the key techniques of writing the Silverlight for Windows Phone 7 based game.
  • Part 6 In this last article, we are going to continue to research into the easy and difficult aspects in creating the Silverlight based game, with an eye to the Android platform based version.
  • <<  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


    Create Android AngryBirds Game Using WiEngine SDK -Part 1
    AngryBirds, as a strategy puzzle mobile game developed by Finnish computer game developer Rovio Mobi...
    Integrate Lua into Your Android Games
    In this article, we will show interests in the interoperations between Lua and Java, especially in t...
    Create Android AngryBirds Game Using WiEngine SDK -Part 2
    Starting from this article I'm going to introduce how to compose the main UIs in creating the AngryB...
    Windows Phone Fast Application Switching and Page State
    An overview of fast application switching and page state in Windows Phone.
    Create Android AngryBirds Game Using WiEngine SDK -Part 3
    In the second part of this series, I introduced how to create most of the gadgets in the prelude scr...
    Top
     
     
     

    Please login to rate or to leave a comment.