Lab: Move an object using Silverlight and XNA in Windows Phone Part 1

Charles Petzold free eBook is great, except that it doesn’t cover the use of Sliverlight-XNA tools that are in the current version of Windows Phone.

One of the most reliable source on how to use the Silverlight XNA hybrid is the MSDN Article at:

In he Silverlight/XNA hybrid, you are working with two tools: Silverlight which uses XAML for the Presentation layer, and the XNA layer which can do a presentation layer and high speed connection with GPU, etc.

In the default template you have a Main Page and a Game Page.  The Main Page has a button that sends you to the game page which by default opens the default XNA “blue” game.  The Game Page xaml and class (in my examples are CSharp, but could be VB).

When you look at the initial MainPage.XAML, the work is done in the following:

image

The Click event is the way that the XAML page communicates with the “code behind”, when there is an existing event you can right click on it and then select the “Navigate to Event Handler”, in this case you will see:

You are then transported to the following event, events vary, and this event was created by the template (or actually the author of the template):

image

This is how the template author decided to navigate to the Gamepage.xaml.  There are a number of ways to do this, but this is efficient.

If you click on the button you then “Navigate” to the game page, and when that opens you get the XNA “blue” game or the cornflower blue screen that you would get with a regular XNA game.  Like XNA, the class and class scope fields are constructed:  Add the code or variables (a type of field):

Code Snippet

  1. public partial class GamePage : PhoneApplicationPage
  2.     {
  3.         //This is the class scope area, it is where you place
  4.         //or declare variables that will be used in the entire
  5.         //class
  6.         ContentManager contentManager;
  7.         GameTimer timer;
  8.         SpriteBatch spriteBatch;
  9.         /************Code Added Begin*******************/
  10.         /************Add Textures***********************/
  11.         //Add three textures, one to hold a changing texture and one to hold a specific texture or picture
  12.         /// <summary>
  13.         /// The texture with texture is to be used has a holder
  14.         /// </summary>
  15.         Texture2D holderTexture;
  16.         /// <summary>
  17.         /// Use this for the enenmy image
  18.         /// </summary>
  19.         Texture2D enemyTexture;
  20.         /// <summary>
  21.         /// Use this for the friendly image
  22.         /// </summary>
  23.         Texture2D friendlyTexture;
  24.         /*************End Adding Textures****************/
  25.         /************Add Vector**************************/
  26.         /// <summary>
  27.         /// A vector to show the position of the texture
  28.         /// </summary>
  29.         Vector2 spritePosition;
  30.         /// <summary>
  31.         /// A vector to use for the speed of the texture
  32.         /// </summary>
  33.         Vector2 spriteSpeed = new Vector2(100.0f, 100.0f);
  34.         /*************End Adding Vectors*****************/
  35.         /*************Code Adding End********************/

 

Unlike XNA the first procedure fired is the OnNavigatedTo, here is the example of the OnNavigatedTo method.  Here you would add things that need to be loaded, like images, etc.which is shown in the code below:

Code Snippet

  1. protected override void OnNavigatedTo(NavigationEventArgs e)
  2.   {
  3.       // Set the sharing mode of the graphics device to turn on XNA rendering
  4.       SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);
  5.  
  6.       // Create a new SpriteBatch, which can be used to draw textures.
  7.       spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);
  8.  
  9.       // TODO: use this.content to load your game content here
  10.       /***************Code Added begin***********************************/
  11.       if (null == holderTexture)
  12.       {
  13.           enemyTexture = contentManager.Load<Texture2D>("enemy");
  14.           friendlyTexture = contentManager.Load<Texture2D>("friendly");
  15.  
  16.  
  17.           // Start with the red rectangle.
  18.           holderTexture = friendlyTexture;
  19.       }
  20.       /***************Code Added end***********************************/
  21.  
  22.       // Start the timer
  23.       timer.Start();
  24.  
  25.       base.OnNavigatedTo(e);
  26.   }

You will need to add two images to the Solution, right click on the content project and add your existing images, I added two images named enemy.jpg and friendly.jpg

image

Now add the OnUpdate code, this is identical to the MSDN Example, but we are going to make a change by “refactor” and extract method, see the steps after this entry:

Code Snippet

  1. private void OnUpdate(object sender, GameTimerEventArgs e)
  2.  {
  3.      // Move the sprite by speed, scaled by elapsed time.
  4.      spritePosition += spriteSpeed * (float)e.ElapsedTime.TotalSeconds;
  5.      /***************Code Added Begin***********************************/
  6.      int MinX = 0;
  7.      int MinY = 0;
  8.      int MaxX = SharedGraphicsDeviceManager.Current.GraphicsDevice.Viewport.Width - holderTexture.Width;
  9.      int MaxY = SharedGraphicsDeviceManager.Current.GraphicsDevice.Viewport.Height - holderTexture.Height;
  10.  
  11.      // Check for bounce.
  12.      if (spritePosition.X > MaxX)
  13.      {
  14.          spriteSpeed.X *= -1;
  15.          spritePosition.X = MaxX;
  16.      }
  17.  
  18.      else if (spritePosition.X < MinX)
  19.      {
  20.          spriteSpeed.X *= -1;
  21.          spritePosition.X = MinX;
  22.      }
  23.  
  24.      if (spritePosition.Y > MaxY)
  25.      {
  26.          spriteSpeed.Y *= -1;
  27.          spritePosition.Y = MaxY;
  28.      }
  29.      else if (spritePosition.Y < MinY)
  30.      {
  31.          spriteSpeed.Y *= -1;
  32.          spritePosition.Y = MinY;
  33.      }
  34.      /***************Code Added End***********************************/
  35.  
  36.  }

Select the code you want to extract, as shown:

image

Then right click and select Refactor-Extract Method:

image

Enter a name for your refactor code:

image

 

You will get a method call in your OnUpdate methods and you will get a method with the name you gave it:

Code Snippet

  1. private void SpritePostionSpeed()
  2. {
  3.     /***************Code Added Begin***********************************/
  4.     int MinX = 0;
  5.     int MinY = 0;
  6.     int MaxX = SharedGraphicsDeviceManager.Current.GraphicsDevice.Viewport.Width - holderTexture.Width;
  7.     int MaxY = SharedGraphicsDeviceManager.Current.GraphicsDevice.Viewport.Height - holderTexture.Height;
  8.  
  9.     // Check for bounce.
  10.     if (spritePosition.X > MaxX)
  11.     {
  12.         spriteSpeed.X *= -1;
  13.         spritePosition.X = MaxX;
  14.     }
  15.  
  16.     else if (spritePosition.X < MinX)
  17.     {
  18.         spriteSpeed.X *= -1;
  19.         spritePosition.X = MinX;
  20.     }
  21.  
  22.     if (spritePosition.Y > MaxY)
  23.     {
  24.         spriteSpeed.Y *= -1;
  25.         spritePosition.Y = MaxY;
  26.     }
  27.     else if (spritePosition.Y < MinY)
  28.     {
  29.         spriteSpeed.Y *= -1;
  30.         spritePosition.Y = MinY;
  31.     }
  32.     /***************Code Added End***********************************/
  33. }

Now add code to the OnDraw method:

Code Snippet

  1. private void OnDraw(object sender, GameTimerEventArgs e)
  2.         {
  3.             SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue);
  4.  
  5.             // TODO: Add your drawing code here
  6.             /***************Code Added Begin***********************************/
  7.             SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.Black);
  8.  
  9.             // Draw the sprite
  10.             spriteBatch.Begin();
  11.  
  12.             // Draw the rectangle in its new position
  13.             spriteBatch.Draw(holderTexture, spritePosition, Color.White);
  14.  
  15.             spriteBatch.End();
  16.  
  17.             /***************Code Added End*************************************/
  18.  
  19.         }

If you run your program, not much happens, just a black screen.  See the next blog for the XAML code.