• File → New Project

    Resources and Content from our Phone Camps


    I’ve run a couple of phone camps so far, the largest and most in depth being the 2-day phone camp hosted by Nokia in Sunnyvale. At the camps, and during my work with developers and designers at other events, there are a number of resources that get requested quite often, so I wanted to put together a post that I can link to and point towards in the future. Please let me know if you think that I’m forgetting anything, and I’ll make sure to keep my list up to date.


    Windows Phone Getting Started -

    Visit the Getting Started page to download the Windows Phone SDK, get more information on the Marketplace and how to monetize your apps and games, and explore the documentation and online communities.

    Silverlight Toolkit -

    The Silverlight Toolkit includes some controls like the DatePicker and WrapPanel that you can drop into your application just like the tools that are included in the SDK. You can download a sample app as a xap that can be deployed to your device or the emulator to try out the included tools and see if they’re right for you.

    Windows Azure Toolkit for Windows Phone -

    Put the cloud on your phone with the Windows Azure Toolkit. While the power and storage on mobile devices continue to increase, one of the most important things you get is an internet connection. By taking advantage of Windows Azure, your application back end can scale and grow with the needs of your users.

    Geo Augmented Reality Toolkit (GART) -

    Updates to the Windows Phone in 7.5 have opened up Augmented Reality possibilities through the live camera stream and motion API. The Geo AR Toolkit makes it possible to create location enabled AR applications without having to know Linear Algebra and geospatial math.

    WP7 Tombstone Helper -

    If you want to quickly and easily persist your application state to isolated storage, the Tombstone Helper might be just what you need. With a couple of lines of code, you can save and restore state and make it easier to allow users to come back to your application in a state they expect.


    Join the Marketplace -

    Joining the Marketplace gives you the ability to submit your apps and games, as well as developer unlock up to three devices so you can test your project. Student developers registered through DreamSpark can join the Marketplace for free, and developer unlock one device. More information on DreamSpark below.


    App Hub Forums -

    If you have questions, the forums are a great place to find answers. Between the Microsoft employees and community members who frequent the forums, you’re sure to get pointed in the right direction. Of course, remember that you can learn more by teaching someone than by being taught, so helping out others on the forums is a great way to increase your skills.

    Windows Phone Developer Blog -

    The Windows Phone Developer Blog is a great place to find out about developer programs, contests, device news, and to get the latest on what’s happening in the Windows Phone world, from the developer’s perspective.


    Windows Phone How-To Index -

    If you want to do something on the Windows Phone and aren’t sure where to start, start here. Through the articles, you can pick up an understanding of any topic on the platform to jump start your own development.


    BizSpark for Startups -

    If you’re a startup and want to get some tools and support, BizSpark is made for you. Through the BizSpark program, you can get access to a suite of tools including an MSDN Premium subscription, access to Azure, production licenses, training, and more.

    DreamSpark for Students -

    If you’re a student, you can register for DreamSpark and get a free Marketplace account to begin testing and deploying your phone apps and games. In addition, you can download free tools like Visual Studio Professional and Expression Studio Ultimate, and get access to training from Pluralsight On-Demand.

  • File → New Project

    Building a Language Learning Game (QuizGame)


    This week we’ll be starting a new game for the Windows Phone. We’ll be using Silverlight this time around, and building a language learning game. The idea behind the game is to make use of a database of words and meanings, pick a word, and give four possible definitions. I actually originally built the first version of this game in XNA, and when I redid it in Silverlight, the implementation ended up being much easier. This week, we’ll start with a new Silverlight project, and walk through what that gives you. We’ll also look at a source of graphics we’ll be using for the game.

    To begin with, load up Visual Studio 2010 Express for Windows Phone, and choose File –> New Project, and under the Silverlight for Windows Phone templates, choose Windows Phone Application. In the Name field, type QuizGame, then click OK. You’ll get a new solution containing a single project with a few files. The basic structure a Silverlight application is a set of XAML files, containing markup that defines the user interface, and .cs files with code behind. In the MainPage.xaml file, you’ll get a visual desginer with a few elements in it. The layout is done through a Grid element containing a StackPanel with two TextBlocks. When you run the application, the emulator will pop up and display the application, looking something like the following:


    The numbers on the right of the page is a frame rate counter. You can turn it on or off using the following line in the App.xaml.cs file’s constructor.

    Enabling the Frame Rate
    1. Application.Current.Host.Settings.EnableFrameRateCounter = true;

    The other important files in the project are the ApplicationIcon.png file, the icon that will appear in the list of apps on the phone, Background.png, the image to display when your application is "pinned" to the Start screen, and SplashScreenImage.jpg, the splash screen that will be displayed when you launch the application.

    We’ll be getting deeper into the XAML next week when we lay out the user interface. This week, we’ll finish off by looking at the source of images we’ll be using. There’s a great resource over at where an artist occasionally posts sets of graphics like the one we will be using. The post in question is Danc's Miraculously Flexible Game Prototyping Tiles.

    Here’s an example of the type of graphics we’ll be using.

    Character Cat GirlCharacter Princess GirlSpeechBubble

    StarGem GreenGem OrangeHeart

    See you next week, when we’ll set up the game interface.

  • File → New Project

    Using the Accelerometer (TriangleShooter)


    This week, we’ll be using the accelerometer to move the player around. For those of you without a device, this one is going to be a bit tricky, as the emulator has no support for the accelerometer at this time. To do this, we’ll put in a check to see whether we are running on a device or an emulator, and use the accelerometer if it’s the device, and multi-touch if it’s the emulator. To begin, grab the latest version of the code from the SkyDrive share.

    In order to use the accelerometer, we’ll need to add an assembly reference to Microsoft.Devices.Sensors, and to test if the game is running on the emulator or a device, we add a reference to Microsoft.Phone. To add the reference, right-click on the references folder in the TriangleShooter project, choose Add Reference, and choose the two references from the list. Additionally, the following Using statement will need to be added for easy access to the Accelerometer:

    Assembly for Accelerometer
    1. using Microsoft.Devices.Sensors;

    We’ll create a variable for the Acceleromter called accelerometer:

    Accelerometer Variable
    1. Accelerometer accelerometer;

    We’ll check to see if we are running on the device, and if so, initialize the variable, set up a method that will handle the accelerometer, and start the monitoring.

    Initializing the Accelerometer
    1. if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Device)
    2. {
    3.     accelerometer = new Accelerometer();
    4.     accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);
    5.     try
    6.     {
    7.         accelerometer.Start();
    8.     }
    9.     catch (AccelerometerFailedException)
    10.     {
    11.     }
    12. }

    The method monitoring the reading changed event will update the position and rotation similar to the method we used around multi-touch.

    Accelerometer ReadingChanged
    1. void accelerometer_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
    2. {
    3.     if (!isPlayerDead && player != null)
    4.     {
    5.         Vector2 direction = new Vector2(Math.Max(-.5f, Math.Min(.5f, (float)-e.Y)), Math.Max(-.5f, Math.Min(.5f, (float)-e.X)));
    7.         player.Rotation = (float)(Math.Atan2(direction.Y, direction.X));
    9.         player.Position += direction * player.Speed;
    11.         player.Position = new Vector2(Math.Min(Math.Max(player.Position.X, 0), 800), Math.Min(Math.Max(player.Position.Y, 0), 480));
    12.     }
    13. }

    If you make only these changes, the accelerometer will work, but the player won’t move around, because we never actually set the player speed. We can update the player initialization to the following to make that happen.

    Player Initialization
    1. player = new Player() { Avatar = txPlayer, Position = new Vector2(100f, 240f), Rotation = 0f, Speed = 15f };

    Finally, we’ll update the UpdatePlayer method to check if the game is running on the emulator, and use the multi-touch if it is.

    1. private void UpdatePlayer()
    2. {
    3.     if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator)
    4.     {
    5.         foreach (TouchLocation tl in TouchPanel.GetState())
    6.         {
    7.             if (tl.State == TouchLocationState.Pressed)
    8.             {
    9.                 if (movementId == 0)
    10.                 {
    11.                     movementId = tl.Id;
    12.                 }
    13.             }
    15.             if (tl.Id == movementId)
    16.             {
    17.                 Vector2 direction = tl.Position - player.Position;
    19.                 if (direction.LengthSquared() > 100)
    20.                 {
    21.                     direction.Normalize();
    23.                     player.Rotation = (float)(Math.Atan2(direction.Y, direction.X));
    25.                     player.Position += direction * 10;
    26.                 }
    27.             }
    29.             if (tl.State == TouchLocationState.Released)
    30.             {
    31.                 if (tl.Id == movementId)
    32.                 {
    33.                     movementId = 0;
    34.                 }
    35.             }
    36.         }
    37.     }
    38. }

    Now we run with multi-touch on the emulator, and the accelerometer on the device.

    At this point, we’re pretty complete as far as the game goes. There are a few things we can do to clean up the code, and to improve the gameplay, and I will post updates as I continue with the project, but next week, we’ll be introducing a new project, so stay tuned.

    Download the latest version of the source code.

  • File → New Project

    Tweaking and Refactoring (TriangleShooter)


    This week, we’ve got a good base for the TriangleShooter game. It shoots, scores, persists high score, has audio, it really gives you something to work off of. To make it easier to work from, this time around, we’re going to tweak a few things and refactor the source to be more readable and modifiable, which will result in a code base you can extend on your own to improve or re-imagine the game. There are still a few things I want to do to the game, as well, and this will get us in a good place to begin doing so. So let’s get started. You can prepare by grabbing the source code from last week over at the SkyDrive share.

    Now before we get to the refactoring, there is one thing that I need to change. The player had been starting at (0,0), the top left of the play space, which was okay most of the time, but could get you killed if an enemy decided to spawn there. Since the enemies spawn around the edges, I want to start by moving the starting location to somewhere away from the edge, to give you a fighting chance at doing better in the game. To do this, we’ll update the initialization of the player in the NewGame function to the following:

    Player NewGame Initialization
    1. player = new Player() { Avatar = txPlayer, Position = new Vector2(100f, 240f), Rotation = 0f };

    Now we’re ready to start refactoring. The big thing we’re going to do here is move related blocks of code out into methods that we’ll call. If you look through the Update method, there are some blocks of code that can easily be pulled out to distinct methods. We’ll end up getting the following methods:

    Update Methods
    1. UpdatePlayer();
    3. UpdateEnemies();
    5. SpawnEnemies(gameTime);
    7. ShootBullets(gameTime);
    9. UpdateBullets();

    The source is a simple copy/paste out of Update, giving us the following method bodies:

    1. private void UpdatePlayer()
    2. {
    3.     foreach (TouchLocation tl in TouchPanel.GetState())
    4.     {
    5.         if (tl.State == TouchLocationState.Pressed)
    6.         {
    7.             if (movementId == 0)
    8.             {
    9.                 movementId = tl.Id;
    10.             }
    11.         }
    13.         if (tl.Id == movementId)
    14.         {
    15.             Vector2 direction = tl.Position - player.Position;
    17.             if (direction.LengthSquared() > 100)
    18.             {
    19.                 direction.Normalize();
    21.                 player.Rotation = (float)(Math.Atan2(direction.Y, direction.X));
    23.                 player.Position += direction * 10;
    24.             }
    25.         }
    27.         if (tl.State == TouchLocationState.Released)
    28.         {
    29.             if (tl.Id == movementId)
    30.             {
    31.                 movementId = 0;
    32.             }
    33.         }
    34.     }
    35. }
    1. private void UpdateEnemies()
    2. {
    3.     foreach (Enemy enemy in enemies)
    4.     {
    5.         enemy.Rotation += ((float)Math.PI / 30f) % ((float)Math.PI * 2);
    7.         Vector2 enemyDirection = player.Position - enemy.Position;
    9.         if (enemyDirection.LengthSquared() > enemy.Speed * enemy.Speed)
    10.         {
    11.             enemyDirection.Normalize();
    13.             enemy.Position += enemyDirection * enemy.Speed;
    14.         }
    16.         if (new Rectangle((int)enemy.Position.X - enemy.Avatar.Width / 2, (int)enemy.Position.Y - enemy.Avatar.Height / 2, enemy.Avatar.Width, enemy.Avatar.Height).Contains((int)player.Position.X, (int)player.Position.Y))
    17.         {
    18.             triangleColor = Color.Red;
    19.             isPlayerDead = true;
    20.             SaveToFile();
    21.         }
    22.     }
    23. }
    1. private void SpawnEnemies(GameTime gameTime)
    2. {
    3.     timeToSpawn -= gameTime.ElapsedGameTime;
    5.     if (timeToSpawn < TimeSpan.Zero)
    6.     {
    7.         Vector2 spawnPosition;
    8.         switch (random.Next(4))
    9.         {
    10.             case 0:
    11.                 spawnPosition = new Vector2(0, random.Next(480));
    12.                 break;
    13.             case 1:
    14.                 spawnPosition = new Vector2(800, random.Next(480));
    15.                 break;
    16.             case 2:
    17.                 spawnPosition = new Vector2(random.Next(800), 0);
    18.                 break;
    19.             case 3:
    20.                 spawnPosition = new Vector2(random.Next(800), 480);
    21.                 break;
    22.             default:
    23.                 spawnPosition = Vector2.Zero;
    24.                 break;
    25.         }
    27.         switch (random.Next(4))
    28.         {
    29.             case 0:
    30.                 enemies.Add(new Enemy() { Position = spawnPosition, Rotation = 0f, Avatar = txEnemy3, Speed = 3f });
    31.                 break;
    32.             case 1:
    33.                 enemies.Add(new Enemy() { Position = spawnPosition, Rotation = 0f, Avatar = txEnemy4, Speed = 3.5f });
    34.                 break;
    35.             case 2:
    36.                 enemies.Add(new Enemy() { Position = spawnPosition, Rotation = 0f, Avatar = txEnemy5, Speed = 4f });
    37.                 break;
    38.             case 3:
    39.                 enemies.Add(new Enemy() { Position = spawnPosition, Rotation = 0f, Avatar = txEnemy6, Speed = 4.5f });
    40.                 break;
    41.             default:
    42.                 break;
    43.         }
    45.         timeToSpawn = new TimeSpan(0, 0, 0, 0, random.Next(500) + 250);
    46.     }
    47. }
    1. private void ShootBullets(GameTime gameTime)
    2. {
    3.     timeToShoot -= gameTime.ElapsedGameTime;
    5.     if (timeToShoot <= TimeSpan.Zero)
    6.     {
    7.         timeToShoot = new TimeSpan(0, 0, 0, 0, ShootDelay);
    8.         bullets.Add(new Bullet() { Avatar = txBullet, Position = new Vector2(player.Position.X + player.Avatar.Width * (float)Math.Cos(player.Rotation), player.Position.Y + player.Avatar.Height * (float)Math.Sin(player.Rotation)), Rotation = player.Rotation, Speed = 15f });
    9.         fire.Play(.5f, 0f, 0f);
    10.     }            
    11. }

    1. private void UpdateBullets()
    2. {
    3.     foreach (Bullet b in bullets.ToList())
    4.     {
    5.         b.Position = new Vector2(b.Position.X + b.Speed * (float)Math.Cos(b.Rotation), b.Position.Y + b.Speed * (float)Math.Sin(b.Rotation));
    7.         if (!graphics.GraphicsDevice.Viewport.Bounds.Contains(new Point((int)b.Position.X, (int)b.Position.Y)))
    8.         {
    9.             bullets.Remove(b);
    10.         }
    11.         else
    12.         {
    13.             foreach (Enemy enemy in enemies.ToList())
    14.             {
    15.                 if (new Rectangle((int)enemy.Position.X - enemy.Avatar.Width / 2, (int)enemy.Position.Y - enemy.Avatar.Height / 2, enemy.Avatar.Width, enemy.Avatar.Height).Contains((int)b.Position.X, (int)b.Position.Y))
    16.                 {
    17.                     bullets.Remove(b);
    18.                     enemies.Remove(enemy);
    19.                     enemyHit.Play();
    20.                     score++;
    21.                     if (score > highScore)
    22.                     {
    23.                         highScore = score;
    24.                     }
    25.                     break;
    26.                 }
    27.             }
    28.         }
    29.     }
    30. }

    This makes things easier to update because we won’t be mixing code that doesn’t belong in other blocks. For example, next week, I’ll be adding in code to support the accelerometer, so I can just change up the UpdatePlayer method, and nothing else needs changed!

    Download the latest version of the source code.

  • File → New Project

    Adding Sound Effects (TriangleShooter)


    This week, we’re going to liven the game up a bit by adding sound effects. While I am pretty amazing at drawing triangles and other figures that you can create without any artistic skills, I have even less skills making sounds. Luckily, there are some places we can get some free sounds to use in our game. We’ll be using a collection of sounds from the AppHub’s SoundLab project, so you can grab that, and pick up the source code from last week from the SkyDrive share.

    This one is going to actually be pretty easy. To start with, we’ll grab the sounds from the SoundLab project, and pick a couple that we think might work for the game. You could go with some gun sounds if you are feeling in a more aggressive mood, but I feel that some of the sounds in the UI folder actually work better for the feel of the game. I picked UI_Misc13.wav for the sound of a bullet hitting an enemy, and UI_Misc17.wav for the shooting sound. So the first thing we need to do is grab the files we picked, and drop them into the TriangleShooterContent project. Once they are added in, we can set up a variable for them, load them from the content project, and then play them.

    The variables are of type SoundEffect, so we’ll set one up for firing, and the other for when the enemy gets hit.

    SoundEffect Variables
    1. SoundEffect fire;
    2. SoundEffect enemyHit;

    Loading the content is straightforward and similar to the previous loading of content we’ve done.

    1. fire = Content.Load<SoundEffect>("UI_Misc17");
    2. enemyHit = Content.Load<SoundEffect>("UI_Misc13");

    And playing them is a simple matter as well. The collision sound is good how it is, so we don’t need to tweak it at all. We can just use the default method signature with no arguments.

    Code Snippet
    1. if (new Rectangle((int)enemy.Position.X - enemy.Avatar.Width / 2, (int)enemy.Position.Y - enemy.Avatar.Height / 2, enemy.Avatar.Width, enemy.Avatar.Height).Contains((int)b.Position.X, (int)b.Position.Y))
    2. {
    3.     bullets.Remove(b);
    4.     enemies.Remove(enemy);
    5.     enemyHit.Play();
    6.     score++;
    7.     if (score > highScore)
    8.     {
    9.         highScore = score;
    10.     }
    11.     break;
    12. }

    The firing sound effect is a bit loud for how often it happens, so we use the overload that allows you to define the volume, pitch modification, and panning. about 50% volume seems good.

    Shooting with a sound effect
    1. if (timeToShoot <= TimeSpan.Zero)
    2. {
    3.     timeToShoot = new TimeSpan(0, 0, 0, 0, ShootDelay);
    4.     bullets.Add(new Bullet() { Avatar = txBullet, Position = new Vector2(player.Position.X + player.Avatar.Width * (float)Math.Cos(player.Rotation), player.Position.Y + player.Avatar.Height * (float)Math.Sin(player.Rotation)), Rotation = player.Rotation, Speed = 15f });
    5.     fire.Play(.5f, 0f, 0f);
    6. }

    And really, that’s it. Well that was easy. Next week, we’ll refactor the code to make it easier to read and make some tweaks to the gameplay.

    Download the latest version of the source code.

Page 2 of 8 (37 items) 12345»