• 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.

  • File → New Project

    Back from the Phone Camps!


    Over the last couple months, I’ve been spending a lot of my time on the road presenting at at least a Phone Camp a week. We did nine cities in the West Region, and of those, I presented at seven. I also made it to a couple of Code Camps, and helped out at some of our other major events like the HTML 5 Web Camp. If you didn’t get a chance to attend one of the camps, and want to see me in action, I was recorded at the Sunnyvale Phone Camp hosted at Nokia, and the recordings are available through the links below.

    Part 1: Windows Phone 7.5 Overview for Developers

    watch it here

    Part 2: Building Windows Phone 7.5 Applications with Visual Studio 2010

    watch it here (Me!)

    Part 3: Building Windows Phone 7.5 Apps with Silverlight

    watch it here

    Part 4: Windows Phone 7.5 Fast Application Switching, Tombstoning and Multitasking

    watch it here (Me!)

    Part 5: Live Tiles and Push Notifications

    watch it here

    Part 6: Building Games for Windows Phone 7.5

    watch it here (Me!)

    Part 7: Monetizing a Windows Phone 7.5 Application

    watch it here


    Hi Everybody

    Being at all those camps was incredibly fun, but of course it meant that I was pretty busy. In the little free time that I had, I tried to keep up with the emails I had coming in, but I could only get so far each time before I had to rush off to the next event. Over the next few days I hope to get through the remainder of what I have sitting in my inbox, but if you haven’t heard back from me I recommend you send me a ping with the original email to bump yourself to the top of my inbox, since my process is to go from the newest emails back.

    I also got a chance to meet some really cool people on the road, and hope to do some more events in some locations I hadn’t gotten much of a chance to visit like Portland. We’re working on the next series of events, including a few full day Game Development Camps where we’ll be going through how to get your game up and running using XNA, combining Silverlight and XNA, and going multi-platform. We’re still looking at whether we can get enough people in some of the cities, so if you want us to come to you, let me know.


    The other thing I’m working on right now is getting my projects that I’ve been showing at all the camps to a point where they are ready to go online. Similar to the TriangleShooter series I posted starting about a year ago, I have a few other projects I will be chunking out into consumable slices. Of course, I still have the Language Learning Game, but I also have the first seven steps of an Augmented Reality sample in Silverlight, am working on the open source Geo Augmented Reality Toolkit over at, a couple projects around the .NET Micro Framework using Netduino and Gadgeteer, and have four more projects that I will be putting into the marketplace and sharing code for. I’ll post updates here on my blog, and am working on recording video walkthroughs to be able to demonstrate everything more easily than screenshots, which is pretty important for samples like the Augmented Reality bit. I’m expecting to post at twice a week, with one of those posts being a continuation of whatever developer series I’m working towards.


    If you are local to the Silicon Valley, tonight I’ll be at the Hacker Dojo for the final night of our “30 to Launch” event. I’ll be bringing some books to give away to the first people who ask me for them. I’ll also be at the Windows Phone Night Out on Wednesday in San Francisco. I won’t be able to bring books there, but I can see if I can bring something smaller with me to give out.

  • File → New Project

    Upcoming XNA Game Development for Windows Phone Webcast



    AT&T is hosting another webcast to follow up their “An Introduction to Tools & Resources for Windows Phone 7 Application Development” on June 24. This time, Rob Cameron will be presenting on Game Development with XNA, and covering the developer tools, the XNA Framework, and resources to help build quality games for the Windows Phone 7.

    If you missed the last session, you can download the slides and presentation from the AT&T Webcast page:

    An Introduction to Tools & Resources for Windows Phone 7 Application Development

    To sign up for the next session, hit up this one:

    XNA Game Development for Windows Phone 7

    You should also check out the XNA Creators Club Online Education Roadmap

  • File → New Project

    Adding Shooting (TriangleShooter)


    Let’s make TriangleShooter a better game. This time around, we’ll be putting the shooter in TriangleShooter, by adding in the ability for the player to shoot. We’ll be starting with last week’s code, so you can go over and grab that from my SkyDrive share.

    I tried a few different ways of making the player shoot in my development of the game, and the best one I have found so far is to have you always laying out a steady stream of shots. Towards the end of the series, I’ll be doing some play mechanics tweaking, and we can investigate some of the other ways, but that’s how I’m going to do things in this article.

    If you’re going to shoot, you need a bullet. You can get my highly stylized, square bullet from the SkyDrive share. To begin with, download that, then add it into the TriangleShooterContent project by dragging it and dropping it in there. We’ll also need a class to handle the bullet, which is going to look familiar. Create a new class in the TriangleShooter project named Bullet.cs, and set the content to the following:

    1. using Microsoft.Xna.Framework;
    2. using Microsoft.Xna.Framework.Graphics;
    4. namespace TriangleShooter
    5. {
    6.     class Bullet
    7.     {
    8.         public Texture2D Avatar { get; set; }
    9.         public Vector2 Position { get; set; }
    10.         public float Rotation { get; set; }
    11.         public float Speed { get; set; }
    12.     }
    13. }

    We’ll set up the variables at the top of the game class to hold the texture, the list of Bullets, and to monitor the passing time to shoot, along with a constant to tweak the timer a bit.

    Variables for Bullets
    1. const int ShootDelay = 250;
    2. TimeSpan timeToShoot;
    4. List<Bullet> bullets;
    5. Texture2D txBullet;

    In the Initialize method, we set up the list for the bullets, and set the time to shoot from the constant value we set up.

    1. bullets = new List<Bullet>();
    3. timeToShoot = new TimeSpan(0, 0, 0, 0, ShootDelay);

    And add some code into the LoadContent method to load in the texture.

    1. txBullet = Content.Load<Texture2D>("Bullet");

    And now we’ve got everything we need. We only have the Update and Draw to go. The Update is more interesting, so let’s start there.

    1. timeToShoot -= gameTime.ElapsedGameTime;
    3. if (timeToShoot <= TimeSpan.Zero)
    4. {
    5.     timeToShoot = new TimeSpan(0, 0, 0, 0, ShootDelay);
    6.     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 });
    8. }
    10. foreach (Bullet b in bullets.ToList())
    11. {
    12.     b.Position = new Vector2(b.Position.X + b.Speed * (float)Math.Cos(b.Rotation), b.Position.Y + b.Speed * (float)Math.Sin(b.Rotation));
    14.     if (!graphics.GraphicsDevice.Viewport.Bounds.Contains(new Point((int)b.Position.X, (int)b.Position.Y)))
    15.     {
    16.         bullets.Remove(b);
    17.     }
    18.     else
    19.     {
    20.         foreach (Enemy enemy in enemies.ToList())
    21.         {
    22.             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))
    23.             {
    24.                 bullets.Remove(b);
    25.                 enemies.Remove(enemy);
    26.                 break;
    27.             }
    28.         }
    29.     }
    30. }

    The first part of the code is similar to what we do to spawn enemies. We subtract the elapsed time from the remaining time, and if the time is less than zero, we spawn a new bullet, setting it’s position to the front of the player and the rotation to the players rotation. We then update all existing bullets. Because we may need to remove them from the master list, we make a copy in the foreach by using the .ToList() function. We move them in the direction based on their rotation, and see if they have left the bounds of the screen. If they have, we remove them from the update list. To optimize things here, we should do something like create a list of decommissioned bullets, and reuse them rather than creating new ones each time, but we won’t do that this time around. If they are within the bounds of the screen, we check collision with each of the enemies, again using the .ToList() function because we might need to remove items. If they collide, we remove both the bullet, and the enemy that collided with it.

    This is all we need to do, but we do need to draw the bullets. Luckily, this is a simple process, just add a few lines into Draw.

    1. foreach (Bullet b in bullets)
    2. {
    3.     spriteBatch.Draw(b.Avatar, b.Position, null, Color.White, b.Rotation, new Vector2(b.Avatar.Width / 2, b.Avatar.Height / 2), 1f, SpriteEffects.None, 0f);
    4. }

    And now we have shooting!


    Next week, we’ll do some refactoring to make the code easier to work with, and see if we can add in some death behavior.

    Download the latest version of the source code.

  • 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.

Page 5 of 8 (37 items) «34567»