<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9 - Entries tagged with arcade</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Tags/arcade/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9 - Entries tagged with arcade</title>
      <link>http://channel9.msdn.com/Tags/arcade</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Tags/arcade</link>
    <language>en</language>
    <pubDate>Sat, 25 May 2013 06:14:56 GMT</pubDate>
    <lastBuildDate>Sat, 25 May 2013 06:14:56 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>19</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Coding Unreal Tournament3 Bots</title>
      <description><![CDATA[
<p>Have you ever played a first person shooter? Then you've probably played against computer controlled players known as &quot;bots&quot; which are computer programs designed with artificial intelligence. Up until now the only way to do create your own bot for a game
 like Unreal Tournament 3 was to learn a bunch of C&#43;&#43; and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express. So here is a way to do just that.</p>
<h2>Your First Bot</h2>
<p>Once you've created a new bot you'll have a very basic class with just a constructor and an overridden
<b>ProcessActions</b>() method.</p>
<h5><strong>C#</strong></h5>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.Linq;
<span class="kwrd">using</span> System.Text;

<span class="kwrd">using</span> UT3Bots;
<span class="kwrd">using</span> UT3Bots.UTItems;
<span class="kwrd">using</span> System.Threading;
<span class="kwrd">using</span> UT3Bots.Communications;


<span class="kwrd">namespace</span> UT3UserBot
{
    <span class="kwrd">public</span> <span class="kwrd">class</span> MyBot : UTBot
    {

        <span class="rem">//Constructor for your bot</span>
        <span class="kwrd">public</span> MyBot() : <span class="kwrd">base</span> (<span class="str">&quot;174.133.254.34&quot;</span>, <span class="str">&quot;Sitting Duck&quot;</span>, BotMesh.Harbinger, BotColor.Red)
        {
        }


        <span class="rem">//Method to control the bot once it has connected to the server</span>
        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> ProcessActions()
        {
            <span class="rem">//Add code here to perform some actions at specific intevals</span>
        }
    }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Imports</span> System
<span class="kwrd">Imports</span> System.Collections.Generic
<span class="kwrd">Imports</span> System.Linq
<span class="kwrd">Imports</span> System.Text

<span class="kwrd">Imports</span> UT3Bots
<span class="kwrd">Imports</span> UT3Bots.UTItems
<span class="kwrd">Imports</span> System.Threading
<span class="kwrd">Imports</span> UT3Bots.Communications


<span class="kwrd">Namespace</span> UT3UserBot
    <span class="kwrd">Public</span> <span class="kwrd">Class</span> MyBot
        <span class="kwrd">Inherits</span> UTBot

        <span class="rem">'Constructor for your bot</span>
        <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>()
            <span class="kwrd">MyBase</span>.<span class="kwrd">New</span>(<span class="str">&quot;174.133.254.34&quot;</span>, <span class="str">&quot;Sitting Duck&quot;</span>, BotMesh.Harbinger, BotColor.Red)
        <span class="kwrd">End</span> <span class="kwrd">Sub</span>


        <span class="rem">'Method to control the bot once it has connected to the server</span>
        <span class="kwrd">Protected</span> <span class="kwrd">Overloads</span> <span class="kwrd">Overrides</span> <span class="kwrd">Sub</span> ProcessActions()
            <span class="rem">'Add code here to perform some actions at specific intevals</span>
        <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    <span class="kwrd">End</span> <span class="kwrd">Class</span>
<span class="kwrd">End</span> Namespace</pre>
<h2>Setting Up Your Bot</h2>
<p>The first thing you need to do for your bot is configure it with a look and feel, and then actually connect to the server and get in the game. This is pretty straightforward, all you need to do is alter the parameters that are getting sent up to the base
 bot class in the constructor.</p>
<ul>
<li><strong>Server IPAddress</strong> - The first parameter is the IPAddress of the server to connect to. By default this points to the UT3Bots server we have running on the internet (ut.utbots.com), you'll need to alter this to point to the server you need
 to connect to. </li><li><strong>Name</strong> – The name of your bot will be seen on the Visualizer and in game.
</li><li><strong>Bot Mesh</strong> – This is the appearance of your bot on the server.
</li><li><strong>Bot Color</strong> – This is the color of your bot. </li></ul>
<p>Now you are ready to join a UT3 game.</p>
<p>Pressing F5 will build and run your bot. The bot project will load up a little console application which provides info about what your bot is doing.</p>
<h2>Bot's First Sight</h2>
<p>Now that we have a bot in the game we need to make it actually do something. The first thing we are going to make it do is move to a UTNavPoint. This is a location in the game which might hold something interesting. A series of UTNavPoints provide a path
 through the level to interesting items. A bot can travel around a game level by moving from one UTNavPoint to another.
</p>
<p>Within the game framework (UT3RemoteBot.dll), an instance of the UTVector class can be used to express the actual location of something. The location of a UTNavPoint is given by its Location property, which is given as a UTVector value.
</p>
<p>Our bot needs to have a way of keeping track of where it is going so in the UT3UserBot class create a new private UTVector called destinationLocation</p>
<h5><strong>C#</strong></h5>
<pre class="csharpcode"><span class="kwrd">private</span> UTVector destinationLocation;</pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Private</span> destinationLocation <span class="kwrd">As</span> UTVector</pre>
<p>We want our bot to head towards the first navpoint that it “sees”. To do this we place the following code into the
<b>ProcessActions</b>() method. </p>
<h5><strong>C#</strong> </h5>
<pre class="csharpcode"><span class="kwrd">this</span>.destinationLocation = <span class="kwrd">this</span>.GameState.NavPointsVisible[0].Location;</pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Me</span>.destinationLocation = <span class="kwrd">Me</span>.GameState.NavPointsVisible(0).Location</pre>
<p>The<b> GameState </b>property of our bot contains information on the current state of the game.
<b>NavPointsVisible</b> is a list of references to UTNavPoint instances which refer to all of the UTNavPoints a bot can currently see. The above code simply takes the UTVector at position 0 (the first navigation point your bot can see) and sets destinationLocation
 to refer to it. </p>
<p>So at this point the bot has identified the location it wants to move towards, now we have to make it move in that direction.
</p>
<h2>Bot's First Steps<b> </b></h2>
<p>Now we are going to make our bot move to the destination it has selected. Place the following code into the ProcessActions() method just below the code written in the previous example.</p>
<h5><strong>C#</strong></h5>
<pre class="csharpcode"><span class="kwrd">this</span>.Commands.RunTo(<span class="kwrd">this</span>.destinationLocation);</pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Me</span>.Commands.RunTo(<span class="kwrd">Me</span>.destinationLocation)</pre>
<p>The<b> Commands</b> property provides a set of methods which are the commands that your program can give to the bot. There are a wide range of commands, some of which are listed below. For full details you should investigate the API reference.
</p>
<ul>
<li><b>Jump()</b> - Jumps in the air </li><li><b>RotateBy()</b> - Rotates by a specific number of degrees </li><li><b>RunTo()</b> - Runs to a specific location </li><li><b>StartFiring()</b> - Attacks a target or location </li><li><b>StopFiring()</b> - Stops the bot from shooting </li><li><b>StrafeTo()</b> - Strafes to a specific location while looking at another </li></ul>
<p>The <b>RunTo()</b> command is provided with a destination location. When this method is called your bot will start running towards the destination.
</p>
<p>If you execute this program you will see your bot start running towards a navigation point.</p>
<h2>Bot's First Shot</h2>
<p>For the purpose of this example we will next make our bot shoot at the location it is running towards, it is recommended that you change this when creating your own implementation as shooting at an empty UTNavPoint is unlikely to get you many frags.
</p>
<p>Place the following code into the <b>ProcessActions</b>()<b> </b>method just below the code written in the previous example.
</p>
<h5><strong>C#</strong></h5>
<pre class="csharpcode"><span class="kwrd">this</span>.Commands.StartFiring(<span class="kwrd">this</span>.destinationLocation, <span class="kwrd">false</span>);</pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Me</span>.Commands.StartFiring(<span class="kwrd">Me</span>.destinationLocation, <span class="kwrd">false</span>)</pre>
<p>If you execute the program you will see that your bot now shoots at the location as it runs towards it. It will continue running and shooting until you call a method to instruct it to stop, or it runs out of ammo!
</p>
<p>Place the following code into the <b>ProcessActions</b>()<b> </b>method just below the code written in the previous step.
</p>
<h5><strong>C#</strong> </h5>
<pre class="csharpcode"><span class="kwrd">this</span>.Commands.StopFiring();</pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Me</span>.Commands.StopFiring()</pre>
<p>Your bot will now stop shooting.</p>
<p>So you now know how to get your bot to do something in the game. Running around and shooting things is as easy as using the
<b>GameState</b> property to access what your bot can see, and the <b>Commands</b> property to call methods that perform actions.</p>
<h3>Bot's First Reaction</h3>
<p>Now we are going to make the bot react to things that happen in the game. This is done by subscribing to any of the events that the bot exposes through its
<b>Events</b> property. We normally want to subscribe to the game events as soon as the bot starts, so that we get all the juicy information that we can use to make a clever bot. You can do this by attaching an event handler to an event in the constructor for
 your bot.</p>
<p>In this example we will subscribe to the OnSpawned event which is trigged whenever the bot spawns in the game, whether this is the first time, or after it has died.</p>
<p>Place the following code into the <b>constructor</b> of the <b>MyBot</b> class.</p>
<h5><strong>C# </strong></h5>
<pre class="csharpcode"><span class="kwrd">this</span>.Events.OnSpawned &#43;= <span class="kwrd">new</span> EventHandler&lt;BotSpawnedEventArgs&gt;(Events_OnSpawned);</pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">AddHandler</span> <span class="kwrd">Me</span>.Events.OnSpawned, <span class="kwrd">AddressOf</span> Events_OnSpawned</pre>
<p>You also need to add a new method to the class that will be called when the bot spawns.</p>
<p>Place the following method code into the <b>MyBot</b> class.</p>
<h5><strong>C#</strong> </h5>
<pre class="csharpcode"><span class="kwrd">void</span> Events_OnSpawned(<span class="kwrd">object</span> sender, BotSpawnedEventArgs e)
{
    <span class="kwrd">this</span>.Commands.PerformEmote(Emote.PelvicThrust);
} </pre>
<h5><strong>VB</strong></h5>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> Events_OnSpawned(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> BotSpawnedEventArgs)
    <span class="kwrd">Me</span>.Commands.PerformEmote(Emote.PelvicThrust)
<span class="kwrd">End</span> Sub</pre>
<p>Your bot will now start performing some fetching pelvic thrusts whenever it spawns in the game. This won't actually help you get any extra frags, but maybe it'll start a new craze!</p>
<p>There are many different events you can attach handlers to which will allow you to change your bot behavior to react to different circumstances. For full details you should investigate the
<a href="http://www.net.dcs.hull.ac.uk/utbot/APIDoc/index.html">API reference</a> or check out Visual Studio's intellisense.</p>
<h2>Viewing Your Bot In Action</h2>
<p>You can easily find out what your bot is up to by using the special Silverlight 2 visualizer we have created. When you open the visualizer web page in your browser, you can automatically see the status of the server running the Bot game type and get a bird's
 eye view of the game in progress. You can see the waypoints which are marked by green dots and the active players which have their name next to moving circles with a line indicating which way they are facing. From here you can view the game and see what your
 bot is doing as shown in the visualizer screenshot.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9228221/clip_image002.jpg"><img title="clip_image002" height="174" alt="clip_image002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9228221/clip_image002_thumb.jpg" width="269" border="0"></a></p>
<h2>What To Do Next</h2>
<p>Now that you have got your bot into the game and made it move around a bit you can start thinking about making it into a decent player of the game. Take a look at the other members of the
<b>GameMap</b> class so that your bot can look for weapons and health packs and move towards them. Then take a look at the members of the
<b>GameState</b> class for the information that your bot is given about the game around it.
</p>
<p>One thing you will need to add is some way that your bot can be in a particular state at any given time. Sensible states might be &quot;Roaming&quot;, &quot;Hunting&quot;, &quot;Idle&quot;, &quot;Recovering&quot;, etc. Depending on the state your bot is in it will do different things each time
<b>ProcessActions</b> is called. </p>
<p>If it is in the roaming state, for example, it will be looking for a navigation point. If it is in the hunting state it will be chasing other bots. If it is in the recovering state it will be avoiding other bots and looking for a health pack, and so on.
 You can keep track of the state of your bot by creating an enumerated type with the different values. Then your
<b>ProcessActions</b> method can contain a switch statement which makes it behave differently, depending on what it is doing.
</p>
<p>A state machine is just one way you could program your AI, you could make a sophisticated bot that had a way of determining if a result had a positive or negative consequence and then have the bot perform more actions that had a positive consequence. Essentially
 a learning bot, be careful though if your bot takes too long executing <b>ProcessActions</b> it will get out of touch with the game as messages will sit on the queue unprocessed waiting for your code to finish.
</p>
<h3>Conclusion</h3>
<p>With this quick getting started guide you should be able to go about creating your own UT3 Deathmatch player. There are also some very handy hints in the FAQ below about getting your bot on the road to stardom.</p>
<p>If you're feeling particularly brave join our project on CodePlex at <a href="http://www.codeplex.com/UT3Bots">
http://www.codeplex.com/UT3Bots</a> and help pitch in with improving the bot client, the visualizer, or even the server mutator.</p>
<p>Happy Fraggin'!</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:5bbb613d62f0467896eb9e7600cd8dc4">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Coding-Unreal-Tournament3-Bots</comments>
      <itunes:summary>
Have you ever played a first person shooter? Then you&#39;ve probably played against computer controlled players known as &amp;quot;bots&amp;quot; which are computer programs designed with artificial intelligence. Up until now the only way to do create your own bot for a game
 like Unreal Tournament 3 was to learn a bunch of C&amp;#43;&amp;#43; and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express. So here is a way to do just that. 
Your First Bot
Once you&#39;ve created a new bot you&#39;ll have a very basic class with just a constructor and an overridden
ProcessActions() method. 
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using UT3Bots;
using UT3Bots.UTItems;
using System.Threading;
using UT3Bots.Communications;


namespace UT3UserBot
{
    public class MyBot : UTBot
    {

        //Constructor for your bot
        public MyBot() : base (&amp;quot;174.133.254.34&amp;quot;, &amp;quot;Sitting Duck&amp;quot;, BotMesh.Harbinger, BotColor.Red)
        {
        }


        //Method to control the bot once it has connected to the server
        protected override void ProcessActions()
        {
            //Add code here to perform some actions at specific intevals
        }
    }
}



VB
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text

Imports UT3Bots
Imports UT3Bots.UTItems
Imports System.Threading
Imports UT3Bots.Communications


Namespace UT3UserBot
    Public Class MyBot
        Inherits UTBot

        &#39;Constructor for your bot
        Public Sub New()
            MyBase.New(&amp;quot;174.133.254.34&amp;quot;, &amp;quot;Sitting Duck&amp;quot;, BotMesh.Harbinger, BotColor.Red)
        End Sub


        &#39;Method to control the bot once it has connected to the server
        Protected Overloads Overrides Sub ProcessActions()
            &#39;Add code here to perform some actions at specific intevals
        End Sub
    End Class
End Namespace
Setting Up Your Bot
The fi</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Coding-Unreal-Tournament3-Bots</link>
      <pubDate>Tue, 16 Dec 2008 17:32:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Coding-Unreal-Tournament3-Bots</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9228221_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9228221_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Clint Rutkas</dc:creator>
      <itunes:author>Clint Rutkas</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Coding-Unreal-Tournament3-Bots/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Sammy The Snake: An XNA game for the Zune</title>
      <description><![CDATA[
<p><strong>Nick Gravelyn</strong>&nbsp;- <a href="http://www.nickgravelyn.com/">http://www.nickgravelyn.com/</a></p>
<p><b><b>Download: </b><a href="http://codeplex.com/sammythesnake">http://codeplex.com/sammythesnake</a>
<br>
</b><b>Software: </b><a href="http://msdn.com/express/">Visual C# Express Editions</a>,
<a href="http://creators.xna.com/en-US/downloads">XNA Game Studios 3.0</a><b> <br>
Difficulty: </b>Intermediate <br>
<b>Time Required:</b> 8 hours <br>
<b>Cost: </b>Free</p>
<p>Artwork courtesy of George Clingerman of <a href="http://www.xnadevelopment.com/">
XNADevelopment.com</a> <br>
<strong>Side note: </strong>XNA is c# only</p>
<p>In the exciting world of XNA Game Studio, the new big thing is the XNA Game Studio 3.0 Beta. This beta allows developers to glimpse what will be coming with the full release of XNA Game Studio 3.0. One of the largest new features coming with XNA Game Studio
 3.0 is the new ability to create games for Microsoft's Zune media device. What we're going to cover today is how to create a full game for the Zune, specifically a clone of the classic “Snake” game.</p>
<p>To begin you need to make sure you are set up to start working on Zune games. For all the details and instructions you will need for this step, please visit
<a href="http://creators.xna.com/en-us/3.0beta_mainpage">http://creators.xna.com/en-us/3.0beta_mainpage</a>. Once you have read and completed steps one and two, continue on with this tutorial.</p>
<p>Welcome back! Now that you're all set up with XNA Game Studio 3.0 Beta, we can start working on our game. Since we want to test our game as we go forward, we're actually going to create the game as a Windows game first and then simply convert it to be a
 Zune project when we are finished. First open up Visual Studio 2008 or Visual C# 2008 Express and create a new Windows project. Let's call it “SammyTheSnake”. Choose the location to save the project and hit Ok.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image8.png"><img border="0" alt="image" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image8_thumb.png" width="269" height="236"></a>Now that we have the project created
 let's start out first by adding in the content for our game. George Clingerman of
<a href="http://www.xnadevelopment.com/">XNADevelopment.com</a> was nice enough to create some pretty graphics for this tutorial so those are the ones we are going to add to the project. In Visual Studio you will have a panel called the
<i>Solution Explorer</i> which will show you all of the files in your project. In that window you want to find the
<i>Content</i> node of your project. Right click on the <i>Content</i> node and choose Add-&gt;New Folder. Name this new folder “Fonts”. Then add a second folder called “Sprites”. At this point your
<i>Solution Explorer</i> should look like what is to your right:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image11.png"><img border="0" alt="image" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image11_thumb.png" width="212" height="276"></a>Let's continue by adding our content
 files. The easiest way to add the sprites to our project is to simply drag and drop them in from the folder. Another method is to right click on the “Sprites” folder, select Add-&gt;Existing Item. Then you can navigate to the directory where the graphics are,
 select them, and click Ok. When completed you will see all five images are copied into the Sprites directory:</p>
<p>Next we'll create the three fonts that we will be using for the game. To create a font, right click on the “Fonts” folder and select Add-&gt;New Item. In the pop up window you will see an item called a “Sprite Font”. Select that item, name your file “MiniFont.spritefont”,
 and then press Ok. When created it will open up in Visual Studio. The .spritefont file is simply an XML document describing which font you want to use. For our purposes there are only two nodes we need to change. First find the node that looks like this:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">FontName</span><span class="kwrd">&gt;</span>MiniFont<span class="kwrd">&lt;/</span><span class="html">FontName</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <i>FontName</i> node specifies which font we wish to use. Let's change our font to Arial:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">FontName</span><span class="kwrd">&gt;</span>Arial<span class="kwrd">&lt;/</span><span class="html">FontName</span><span class="kwrd">&gt;</span></pre>
<p>Next we need to change the size of the font. Let's find the Size node which, by default, is set to 14:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Size</span><span class="kwrd">&gt;</span>14<span class="kwrd">&lt;/</span><span class="html">Size</span><span class="kwrd">&gt;</span></pre>
<p>And let's change our font to size 10:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Size</span><span class="kwrd">&gt;</span>10<span class="kwrd">&lt;/</span><span class="html">Size</span><span class="kwrd">&gt;</span></pre>
<p>Now that you know how to create fonts, create two more fonts: “MediumFont.spritefont” and “TitleFont.spritefont”. Both fonts should use the Arial font. MediumFont should be size 14 (the default value) and TitleFont should be size 18.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image.png"><img border="0" alt="image" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb.png" width="271" height="406"></a>Now you have all the content our game needs.
 Let's take a look at the <i>Solution Explorer</i> one last time to make sure we have all the files in the correct locations:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image.png"></a></p>
<p>Now that all of the content is in place, we can begin working on the game. Let's start writing that code!</p>
<p>To begin we want to make sure our Windows game looks just like the Zune version will. Since the Zune screen has a resolution of 240 pixels by 320 pixels, we want to make our Windows game run in a window set at 240x320. To do this we just need to add two
 lines of code to our Game1 class's constructor:</p>
<pre class="csharpcode"><span class="kwrd">public</span> Game1()
{
    graphics = <span class="kwrd">new</span> GraphicsDeviceManager(<span class="kwrd">this</span>);
    Content.RootDirectory = <span class="str">&quot;Content&quot;</span>;

    graphics.PreferredBackBufferWidth = 240;
    graphics.PreferredBackBufferHeight = 320;
}</pre>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_3.png"><img title="image" border="0" alt="image" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_3.png" width="347" height="234"></a>The next thing to consider
 is our game's flow. Since we are making a simple game, we are only ever going to have three states in which the game can be in as illustrated by this diagram:</p>
<p>From the diagram we see that our game will have a title screen, some game play, and a game over screen. The arrows represent the changes in game state. From the title screen we can only progress to the in-game screen. From the in-game screen we can either
 quit, going back to the title screen, or we can finish the game and move to the game over screen. From the game over screen we then return to the title screen and the process repeats until the user quits.</p>
<p>Now that we have an idea of how our game will work we will start by creating the framework that will manage our game's state and make sure that we are executing the appropriate code based on the state of the game. First we'll create a new enumeration type
 to represent the three states of our game. In the Game1.cs file right above the declaration for the Game class, add this new enumeration:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">enum</span> GameState
{
    Title,
    InGame,
    GameOver
}</pre>
<p>Now in the actual Game1 class, we need to add a variable to hold the game's state:</p>
<pre class="csharpcode"><span class="kwrd">private</span> GameState state = GameState.Title;</pre>
<p>Now we need to create some new methods which will be used to handle updating and drawing our various states. First let's add three new methods to our Game1 class:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateTitleScreen()
{ }

<span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{ }

<span class="kwrd">private</span> <span class="kwrd">void</span> UpdateGameOver()
{ }</pre>
<p>From the names you can probably see that we have one for each of our three game states. Our UpdateInGame method takes in the GameTime as a parameter because it is used for moving our snake around. The other two game states don't need that value, so they
 have no parameters. Now let's make some changes to the Update method to handle calling each of these methods based on the state of our game:</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Update(GameTime gameTime)
{
    <span class="kwrd">if</span> (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        <span class="kwrd">this</span>.Exit();

    <span class="kwrd">if</span> (state == GameState.Title)
        UpdateTitleScreen();
    <span class="kwrd">else</span> <span class="kwrd">if</span> (state == GameState.InGame)
        UpdateInGame(gameTime);
    <span class="kwrd">else</span> <span class="kwrd">if</span> (state == GameState.GameOver)
        UpdateGameOver();

    <span class="kwrd">base</span>.Update(gameTime);
}</pre>
<p>Now we'll repeat those steps to make three methods for rendering each state and updating the Draw method to call each of them as appropriate. While we're at it, we're also going to change the background from the default of CornflowerBlue to Gray to make
 it a little easier on the eyes with the white text we're going to add later:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawTitleScreen()
{ }

<span class="kwrd">private</span> <span class="kwrd">void</span> DrawInGame()
{ }

<span class="kwrd">private</span> <span class="kwrd">void</span> DrawGameOver()
{ }

<span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Draw(GameTime gameTime)
{
    graphics.GraphicsDevice.Clear(Color.Gray);

    <span class="kwrd">if</span> (state == GameState.Title)
        DrawTitleScreen();
    <span class="kwrd">else</span> <span class="kwrd">if</span> (state == GameState.InGame)
        DrawInGame();
    <span class="kwrd">else</span> <span class="kwrd">if</span> (state == GameState.GameOver)
        DrawGameOver();

    <span class="kwrd">base</span>.Draw(gameTime);
}</pre>
<p>With that our game now has a fully functioning state system. Of course our game only ever has one state since we don't currently change it, and none of the game states do anything, but the functionality is there. Let's move on to create the code that will
 power the title screen.</p>
<p>First we need to add a few strings to our game which will be used on the title screen. Towards the top of your Game1 class, add these string constants:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> gameTitle = <span class="str">&quot;Sammy the Snake!&quot;</span>;
<span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> playInstructions = <span class="str">&quot;Press Play to Begin&quot;</span>;
<span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> quitInsructions = <span class="str">&quot;Press Back to Quit&quot;</span>;</pre>
<p>Now we need to add a few variables to the Game1 class to hold our fonts which we'll be using to render these strings:</p>
<pre class="csharpcode"><span class="kwrd">private</span> SpriteFont titleFont;
<span class="kwrd">private</span> SpriteFont mediumFont;
<span class="kwrd">private</span> SpriteFont miniFont;</pre>
<p>Next we'll go to our <i>LoadContent</i> method and add in the code that will load those .spritefont files we created earlier and store them in these three variables:</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> LoadContent()
{
    spriteBatch = <span class="kwrd">new</span> SpriteBatch(GraphicsDevice);
    titleFont = Content.Load&lt;SpriteFont&gt;(<span class="str">&quot;Fonts/TitleFont&quot;</span>);
    mediumFont = Content.Load&lt;SpriteFont&gt;(<span class="str">&quot;Fonts/MediumFont&quot;</span>);
    miniFont = Content.Load&lt;SpriteFont&gt;(<span class="str">&quot;Fonts/MiniFont&quot;</span>);
}</pre>
<p>After that we also need to add two more variables. The first will store the current frame's input state. The second will store the previous frame's input state. By storing these two values, we will be able to test for when a button gets pressed by verifying
 that the button was down the frame before and is pressed in the current frame.</p>
<pre class="csharpcode"><span class="kwrd">private</span> GamePadState gamePadState;
<span class="kwrd">private</span> GamePadState lastGamePadState;</pre>
<p>Now let's go ahead and make a method which we'll use to test for new button presses for us. We'll take a parameter for which button to test and then check for that button being down in
<i>gamePadState</i> but up in <i>lastGamePadState</i>.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> IsNewButtonPress(Buttons button)
{
    <span class="kwrd">return</span> (gamePadState.IsButtonDown(button) &amp;&amp; lastGamePadState.IsButtonUp(button));
}</pre>
<p>We'll go ahead, now, and modify the game's Update method to handle updating those GamePadState variables we created above. We get the current state right away and then, at the end of the Update method, we store the current state in our last state variable
 for next frame. We also want to remove the default code in there for exiting when the Back button is pressed because we will handle this in our UpdateTitleScreen method:</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Update(GameTime gameTime)
{
    gamePadState = GamePad.GetState(PlayerIndex.One);

    <span class="kwrd">if</span> (state == GameState.Title)
        UpdateTitleScreen();
    <span class="kwrd">else</span> <span class="kwrd">if</span> (state == GameState.InGame)
        UpdateInGame(gameTime);
    <span class="kwrd">else</span> <span class="kwrd">if</span> (state == GameState.GameOver)
        UpdateGameOver();

    lastGamePadState = gamePadState;

    <span class="kwrd">base</span>.Update(gameTime);
}</pre>
<p>With that in place we can move on to filling in our UpdateTitleScreen method. For our simple game, we're going to simply detect the Play/Pause button to start the game and the Back button to exit. These buttons map to the GamePadState's B and Back buttons,
 respectively.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateTitleScreen()
{
    <span class="kwrd">if</span> (IsNewButtonPress(Buttons.Back))
        Exit();

    <span class="kwrd">if</span> (IsNewButtonPress(Buttons.B))
    { }
}</pre>
<p>For now we'll leave the inside of our second if statement empty because we have not implemented the in-game game state at this point.
</p>
<p>Let's now move on to rendering our title screen. We know we are going to have to render three different strings to the screen, so what we're going to do first is write a helper method that will help us write text centered on a point. This will make it easier
 for us so that we don't have to try and calculate where to draw each string individually; we can simply use this one method everywhere we need to draw text.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawText(SpriteFont font, <span class="kwrd">string</span> text, Vector2 position)
{
    Vector2 halfSize = font.MeasureString(text) / 2f;
    position = position - halfSize;

    position.X = (<span class="kwrd">int</span>)position.X;
    position.Y = (<span class="kwrd">int</span>)position.Y;

    spriteBatch.Begin();
    spriteBatch.DrawString(
        font,
        text,
        position, 
        Color.White);
    spriteBatch.End();
}</pre>
<p>This is our first complex code so we're going to take a look at it line by line. The method itself takes in three parameters: the SpriteFont to use for rendering, the text we want to render, and the point at which we want the text centered.</p>
<p>First we use the font's MeasureString method to calculate how big the text will be (in pixels) if rendered with that font. We then divide this size by two and subtract it from the position. Why do we do all of this? In the XNA framework (and most 2D graphics
 APIs) positions of objects are specified using the top-left corner of the object. So by getting half of the size of the object and offsetting the position by it, we are able to set the center point and know that the text will be positioned properly.
</p>
<p>Once we have offset the position, we then cast each of the components to integers. We do this to avoid unnecessary blurring of our text. Since all text is rendered as whole pixels (because there's no such thing as a fractional pixel), having a position that
 is not an integer value will cause the device to try and filter the text to get it to look right, or simply render it incorrectly. So when drawing in 2D, it's always best to cast your positions to integers before using them to render.</p>
<p>Lastly our method uses a simple SpriteBatch routine to draw the text at the desired position using the desired font using the White color.</p>
<p>With that helper method out of the way, we can add three simple lines to the DrawTitleScreen method to draw our title screen:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawTitleScreen()
{
    DrawText(titleFont, gameTitle, <span class="kwrd">new</span> Vector2(120f, 25f));
    DrawText(mediumFont, playInstructions, <span class="kwrd">new</span> Vector2(120f, 200f));
    DrawText(mediumFont, quitInsructions, <span class="kwrd">new</span> Vector2(120f, 225f));
}</pre>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_4.png"><img title="image" border="0" alt="image" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_4.png" width="250" height="349"></a>Now if you run your game,
 you should see a window like this:</p>
<p>If you have an Xbox 360 controller hooked to your computer, you could press the Back button to quit, but otherwise you can simply use the close button of the window to exit the game.</p>
<p>From this point we're going to start working on the gameplay. I am only going to be showing GamePad controls for this (since we are targeting the Zune), so if you don't have an Xbox 360 controller connected to your PC, you are either going to have to deploy
 the game to the Zune each time you want to test or implement keyboard controls. You can skip down to the end of this tutorial where we convert the project to be a Zune game or use other references for that process.</p>
<p>Next we need to add in the game play code itself. Our game is rather simple. At any given time our game will have a single orange on screen, the snake, and a display of the number of oranges consumed. We're going to start with the orange, then handle the
 snake, and finally the scoring system.</p>
<p>To begin any of our rendering we need to get setup with a system for easily rendering our game. Since the whole game is grid based, we are going to make a class whose only purpose is to handle rendering a sprite at a given point using grid coordinates. We'll
 start by creating a new static class called Grid:</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> Grid
{ }</pre>
<p>Next we will define a few constants. The first sets the size of each grid cell. The second is one half of the grid cell size. We will be using a 16x16 pixel area for our grids. This number has been chosen because both 240 and 320 are even divisible by it,
 thus giving us a perfect grid for the resolution. We then have values to represent the largest row and column values in our grid:</p>
<p>Next we'll define a method called <i>PointToVector2</i>. The whole purpose of this method will be to take a
<i>Point</i> value representing cell coordinates and converting them into the pixel coordinates needed to render a sprite. To do this we simply multiply the point's coordinates by the scale and add in the half scale value. We add the half scale so that the
 resulting Vector2 is at the center of the cell. As I said before you always want to convert to integer based coordinates, but since the Point only contains integer values, and all our constants are integers, we don't need to explicitly cast the values to ints:
</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> Vector2 PointToVector2(Point p)
{
    <span class="kwrd">return</span> <span class="kwrd">new</span> Vector2(
        p.X * Scale &#43; HalfScale,
        p.Y * Scale &#43; HalfScale);
}</pre>
<p>The only other method we're going to add to our Grid class is the <i>DrawSprite</i> method.
<i>DrawSprite</i> will handle rendering a given texture at a specific point with a given angle of rotation.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> DrawSprite(
    SpriteBatch spriteBatch, 
    Texture2D texture, 
    Point point, 
    <span class="kwrd">float</span> rotation)
{
    <span class="kwrd">float</span> spriteSize = (<span class="kwrd">float</span>)Math.Max(texture.Width, texture.Height);
    Vector2 origin = <span class="kwrd">new</span> Vector2(texture.Width / 2f, texture.Height / 2f);
    spriteBatch.Draw(
        texture,
        PointToVector2(point),
        <span class="kwrd">null</span>,
        Color.White,
        rotation,
        origin,
        Scale / spriteSize,
        SpriteEffects.None,
        0);
} </pre>
<p>Let's walk through what this method is doing so that we're all clear as to how it works. We first calculate the largest dimension of the texture given to us. We do this so we know how much to scale the sprite to make it fit into a single cell of the grid.
 Then we compute the origin we'll use for rendering. I'll explain the origin below as we go through the parameters of our Draw call.</p>
<p>Next we make a large call to <i>spriteBatch.Draw</i>, where we have lots of variables going in. Let's just explain each one briefly:</p>
<ul>
<li><b>texture </b>– This represents the texture object we want to draw. </li><li><b>PointToVector2(point)</b> – Here we leverage the <i>Grid.PointToVector2 </i>
method we wrote before to convert our grid coordinate to pixel coordinates. </li><li><b>null</b> – This parameter represents the source rectangle used to render. The source rectangle is used to specify a subsection of the area of the texture to use for rendering. Since we want to draw the entire texture, we use null here.
</li><li><b>Color</b>.<b>White</b> – Using white here simply causes the sprite batch to render the texture with no color modifications.
</li><li><b>rotation – </b>The rotation (specified in radians) instructs the sprite batch to rotate the texture as desired.
</li><li><b>origin</b> – Here we use the origin value we calculated earlier. This value specifies how to place, rotate, and scale the texture. What we've done is specified the pixel value of the center of our sprites. The sprites created for us are 32x32 pixels
 making their center point 16x16. Rather than hard coding in that value, we simply divide the width and height by two. By using the center of the texture, our sprite will be positioned such that the second parameter tells the sprite batch where we want the
 center of our texture. It also means that the sprite will be rotated and scaled about its center.
</li><li><b>Scale / spriteSize</b> – Here we use our grid's Scale value and divide it by the size of the sprite. This will cause sprite batch to scale the texture so that it fits completely within a single grid cell.
</li><li><b>SpriteEffects</b>.<b>None</b> – SpriteEffects are used for flipping the texture over the horizontal axis, vertical axis, or both. We don't want to flip the texture, so we specify none.
</li><li><b>0 </b>– The last parameter is the layer depth. This can be used to specify the order in which sprites drawn in the same batch are layered when rendered with zero being the topmost drawn sprites and one being the bottom most drawn sprites. We just use
 zero here because we will be handling the rendering order by hand so that sprites we want lower will be drawn first. In addition we will rarely ever have overlapping sprites, so ordering is hardly an issue for us.
</li></ul>
<p>With the Grid class complete, we can move on to create the Orange class:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Orange
{
    Position = <span class="kwrd">new</span> Point(Grid.MaxColumn / 2, Grid.MaxRow / 2);
}</pre>
<p>Now let's think about what data our orange will need. The two obvious ones are a position and the texture. But we also need a third value: a random number generator which will be used to place the orange in a random place on the screen:</p>
<pre class="csharpcode"><span class="kwrd">public</span> Point Position;
<span class="kwrd">private</span> Texture2D texture;
<span class="kwrd">private</span> Random rand = <span class="kwrd">new</span> Random();</pre>
<p>Now we're going to add three short methods to our Orange class that will handle just about all the functionality we will need for this game:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Reposition()
{
    Position = <span class="kwrd">new</span> Point(rand.Next(Grid.MaxColumn), rand.Next(Grid.MaxRow));
}

<span class="kwrd">public</span> <span class="kwrd">void</span> Load(ContentManager content)
{
    texture = content.Load&lt;Texture2D&gt;(<span class="str">&quot;Sprites/Orange&quot;</span>);
}

<span class="kwrd">public</span> <span class="kwrd">void</span> Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Begin();
    Grid.DrawSprite(spriteBatch, texture, Position, 0f);
    spriteBatch.End();
}</pre>
<p>Our <i>Reposition</i> method is what will generate a random location in our grid at which the orange will be placed. The
<i>Load</i> method requires a <i>ContentManager</i> instance and handles loading our orange texture from file. Lastly the
<i>Draw</i> method takes in a <i>SpriteBatch</i> instance and handles rendering the orange using our Grid class's
<i>DrawSprite</i> method.</p>
<p>Before continuing on, let's give this class a try to make sure it works like we think it should. First let's head to the Game1 class and add a new variable for the orange. We'll also set our starting game state to the InGame playing state:</p>
<pre class="csharpcode"><span class="kwrd">private</span> Orange orange = <span class="kwrd">new</span> Orange();
<span class="kwrd">private</span> GameState state = GameState.InGame;</pre>
<p>Then we need to make sure call the orange's <i>Load</i> method in our <i>LoadContent</i> method:</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> LoadContent()
{
    spriteBatch = <span class="kwrd">new</span> SpriteBatch(GraphicsDevice);
    titleFont = Content.Load&lt;SpriteFont&gt;(<span class="str">&quot;Fonts/TitleFont&quot;</span>);
    mediumFont = Content.Load&lt;SpriteFont&gt;(<span class="str">&quot;Fonts/MediumFont&quot;</span>);
    miniFont = Content.Load&lt;SpriteFont&gt;(<span class="str">&quot;Fonts/MiniFont&quot;</span>);

    orange.Load(Content);
}</pre>
<p>Next we'll go to our <i>UpdateInGame</i> method and add in some code that will call the orange's
<i>Reposition</i> method every second:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    <span class="kwrd">if</span> (gameTime.TotalGameTime.Milliseconds % 1000 == 0)
        orange.Reposition();
}</pre>
<p>Lastly we'll add to the <i>DrawInGame</i> method so that it call's the orange's
<i>Draw </i>method:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawInGame()
{
    orange.Draw(spriteBatch);
}</pre>
<p>Build and run the game. You should see the same gray window with a single orange drawn. Every second the orange will move to a new grid location on the screen.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_5.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_5.png" width="250" height="349"></a>
</p>
<p>Now we will be creating our Snake class:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Snake
{ }</pre>
<p>The Snake class is a bit more complex. Logically let's lay out what data the class will need:</p>
<ul>
<li>A list of points for each segment of the body. </li><li>The four textures (head, straight body piece, angled body piece, and tail) with which we will render the snake
</li><li>A value indicating how fast the snake should be moving. </li><li>A value indicating the snake's current direction and the direction he will be moving next.
</li><li>A value indicating whether or not to extend the snake's length the next time it moves.
</li><li>A timer value so that we can control how often the snake moves from grid cell to grid cell.
</li></ul>
<p>A good amount of data for something that seems rather simple. We'll start by creating an enumeration for those direction values we are going to need:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">enum</span> Direction
{
    Up,
    Down,
    Left,
    Right
}</pre>
<p>Next we'll go ahead and add all the variables to our Snake class itself:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">const</span> <span class="kwrd">float</span> MoveSpeed = .2f; 
<span class="kwrd">private</span> <span class="kwrd">float</span> moveTimer;
<span class="kwrd">private</span> Texture2D head, straight, angle, tail;
<span class="kwrd">private</span> List&lt;Point&gt; bodyPoints = <span class="kwrd">new</span> List&lt;Point&gt;();
<span class="kwrd">private</span> Direction currentDirection = Direction.Right;
<span class="kwrd">private</span> Direction nextDirection = Direction.Right;
<span class="kwrd">private</span> <span class="kwrd">bool</span> extending;</pre>
<p>Everything here should be rather self explanatory. The <i>MoveSpeed</i> represents the number of seconds before the snake proceeds to the next grid cell and the
<i>moveTimer</i> will be used to count up to this value. We then have our four textures, a list for the body points, and two values for the current and next direction. Lastly our bool value to tell us whether the snake should extend the next time it moves.</p>
<p>Now we're going to add a new method called <i>Reset </i>which will be called from the Snake's constructor.
<i>Reset</i> is responsible for placing our Snake it its starting position in the game.</p>
<pre class="csharpcode"><span class="kwrd">public</span> Snake()
{
    Reset();
}

<span class="kwrd">public</span> <span class="kwrd">void</span> Reset()
{
    bodyPoints.Clear();

    bodyPoints.Add(<span class="kwrd">new</span> Point(2, 0));
    bodyPoints.Add(<span class="kwrd">new</span> Point(1, 0));
    bodyPoints.Add(<span class="kwrd">new</span> Point(0, 0));

    currentDirection = Direction.Right;
    nextDirection = Direction.Right;
}</pre>
<p>In the <i>Reset</i> method, first we make sure to clear out the list of points for the snake's body. Next we add three points to the body. The first point sets the position of the head, followed by a single body piece, and lastly the tail. To finish we also
 make sure to reset both the current and next direction values to Right so that the snake begins by heading to the right.</p>
<p>Next we'll make a <i>Load</i> method which, like the Orange class, handles loading in the textures needed to render the snake:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Load(ContentManager content)
{
    head = content.Load&lt;Texture2D&gt;(<span class="str">&quot;Sprites/Head&quot;</span>);
    straight = content.Load&lt;Texture2D&gt;(<span class="str">&quot;Sprites/Straight&quot;</span>);
    angle = content.Load&lt;Texture2D&gt;(<span class="str">&quot;Sprites/Angle&quot;</span>);
    tail = content.Load&lt;Texture2D&gt;(<span class="str">&quot;Sprites/Tail&quot;</span>);
}</pre>
<p>Continuing on we're going to implement the rendering for the snake. This is the most complex part of this entire game, but we'll take it one step at a time to make sure each line of code is explained. First let's add the five methods we'll be using:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Begin();

    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 1; i &lt; bodyPoints.Count - 1; i&#43;&#43;)
    {
        DrawBody(
            spriteBatch, 
            bodyPoints[i], 
            bodyPoints[i - 1], 
            bodyPoints[i &#43; 1]);
    }

    DrawTail(spriteBatch);
    DrawHead(spriteBatch);
    spriteBatch.End();
}

<span class="kwrd">private</span> <span class="kwrd">void</span> DrawHead(SpriteBatch spriteBatch) { }
<span class="kwrd">private</span> <span class="kwrd">void</span> DrawTail(SpriteBatch spriteBatch) { }
<span class="kwrd">private</span> <span class="kwrd">bool</span> IsAnglePiece(Point current, Point last, Point next) { }
<span class="kwrd">private</span> <span class="kwrd">void</span> DrawBody(SpriteBatch spriteBatch, Point current, Point last, Point next) { }
<span class="kwrd">private</span> <span class="kwrd">float</span> GetAngleRotation(Point current, Point last, Point next) { }</pre>
<p>We can see that we have broken the rendering up into multiple methods to make the code a bit more organized. We have the main
<i>Draw </i>method which will be used by our Game1 class to handle drawing the snake. The method has a single
<i>SpriteBatch</i> instance for a parameter. </p>
<p>Then we loop through the <i>bodyPoints</i> list starting on the second item and going up to the second to last item. We intentionally do not use the first or last points because those represent the head and tail, respectively.</p>
<p>After we draw the body, we then draw the tail and head. The order in which we call these methods will affect the graphics to a small degree. The important part is drawing the head last. By doing this we ensure that even when the head and a body piece overlap
 (for instance, when the snake runs into itself) the head will be drawn on top of the body part.</p>
<p>Next we'll go ahead and fill in the <i>DrawHead</i> method:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawHead(SpriteBatch spriteBatch)
{
    Point headPoint = bodyPoints[0];
    Point nextBody = bodyPoints[1];

    <span class="kwrd">float</span> rotation;
    <span class="kwrd">if</span> (headPoint.Y == nextBody.Y - 1)
    {
        rotation = -MathHelper.PiOver2;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (headPoint.Y == nextBody.Y &#43; 1)
    {
        rotation = MathHelper.PiOver2;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (headPoint.X == nextBody.X - 1)
    {
        rotation = MathHelper.Pi;
    }
    <span class="kwrd">else</span>
    {
        rotation = 0f;
    }

    Grid.DrawSprite(spriteBatch, head, headPoint, rotation);
}</pre>
<p>While this looks really complex, it's rather simply once you look at it. First we get out the position of the head and then the first body point after that. What we then do is compare those points to figure out what angle to use when rendering the head.
 Finally we just use the <i>Grid.DrawSprite</i> method to render the head to the screen.</p>
<p>Now we'll fill in the DrawTail method. This method is almost identical to the DrawHead method so there really is no explanation needed:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawTail(SpriteBatch spriteBatch)
{
    Point tailPoint = bodyPoints[bodyPoints.Count - 1];
    Point lastBody = bodyPoints[bodyPoints.Count - 2];

    <span class="kwrd">float</span> rotation;
    <span class="kwrd">if</span> (tailPoint.Y == lastBody.Y - 1)
    {
        rotation = MathHelper.PiOver2;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (tailPoint.Y == lastBody.Y &#43; 1)
    {
        rotation = -MathHelper.PiOver2;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (tailPoint.X == lastBody.X &#43; 1)
    {
        rotation = MathHelper.Pi;
    }
    <span class="kwrd">else</span>
    {
        rotation = 0f;
    }

    Grid.DrawSprite(spriteBatch, tail, tailPoint, rotation);
}</pre>
<p>We'll tackle the <i>IsAnglePiece</i> method next. This method is used by the <i>
DrawBody</i> method to determine if a given point should be drawn with the angled body piece or the straight body piece. To do this we compare the positions of the current body piece, the previous body piece, and the next body piece to determine if they make
 up a right angle or not:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> IsAnglePiece(Point current, Point last, Point next)
{
    <span class="kwrd">return</span> (current.X == last.X &amp;&amp; current.X != next.X &amp;&amp; current.Y != last.Y) ||
           (current.X == next.X &amp;&amp; current.X != last.X &amp;&amp; current.Y != next.Y);
}</pre>
<p>With that completed we can fill in the <i>DrawBody</i> method. This method is also pretty simple:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawBody(SpriteBatch spriteBatch, Point current, Point last, Point next)
{
    <span class="kwrd">if</span> (IsAnglePiece(current, last, next))
    {
        Grid.DrawSprite(
            spriteBatch, 
            angle, 
            current, 
            GetAngleRotation(current, last, next));
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (current.X != last.X)
    {
        Grid.DrawSprite(
            spriteBatch, 
            straight, 
            current, 
            0f);
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (current.Y != last.Y)
    {
        Grid.DrawSprite(
            spriteBatch, 
            straight, 
            current, 
            MathHelper.PiOver2);
    }
}</pre>
<p>First we check to see if the three points comprise and angle. If they do we use the
<i>Grid.DrawSprite</i> method to render the angle texture at the current position. For the angle we utilize the
<i>GetAngleRotation </i>method which we will be filling in later.</p>
<p>If we don't have an angle piece, we then figure out whether the body piece is horizontal or vertical and use that to render the straight body piece with either zero or PiOver2 as the angle.</p>
<p>Finally we come to the <i>GetAngleRotation</i> method. This method takes three Points and determines the angle at which the sprite must be drawn in order to connect the three body pieces. Here's the code for this method:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">float</span> GetAngleRotation(Point current, Point last, Point next)
{
    Point negPiOver2 = <span class="kwrd">new</span> Point(next.X &#43; 1, last.Y - 1);
    Point negPiOver22 = <span class="kwrd">new</span> Point(last.X &#43; 1, next.Y - 1);

    Point pi = <span class="kwrd">new</span> Point(next.X - 1, last.Y - 1);
    Point pi2 = <span class="kwrd">new</span> Point(last.X - 1, next.Y - 1);

    Point piOver2 = <span class="kwrd">new</span> Point(next.X - 1, last.Y &#43; 1);
    Point piOver22 = <span class="kwrd">new</span> Point(last.X - 1, next.Y &#43; 1);

    <span class="kwrd">if</span> (current == negPiOver2 || current == negPiOver22)
    {
        <span class="kwrd">return</span> -MathHelper.PiOver2;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (current == pi || current == pi2)
    {
        <span class="kwrd">return</span> MathHelper.Pi;
    }
    <span class="kwrd">else</span> <span class="kwrd">if</span> (current == piOver2 || current == piOver22)
    {
        <span class="kwrd">return</span> MathHelper.PiOver2;
    }
    <span class="kwrd">else</span>
    {
        <span class="kwrd">return</span> 0f;
    }
}</pre>
<p>The method begins by calculating a set of Points. Each pair of points represents one of the combinations that will result in a particular angle. This can take a little bit to wrap your head around, so if you have trouble visualizing it, I'd recommend grabbing
 (or making) some grid paper and drawing the points out so you can see how they all fall into place.</p>
<p>We then go through and compare the current point to each set of our values. If any match up, we return that value. If none match, we don't have any rotation to apply to the sprite.</p>
<p>That completes the snake's rendering system. It was a pretty big hill to take, but with it behind us we can feel good knowing that the rest of the code will be quite a bit simpler. Before we move on, let's head back to the Game1 class to test out our new
 class and make sure it works.</p>
<p>First we'll add a new variable for the snake:</p>
<pre class="csharpcode"><span class="kwrd">private</span> Snake snake = <span class="kwrd">new</span> Snake();</pre>
<p>Next we head to the <i>LoadContent</i> method and make sure we call the snake's
<i>Load</i> method:</p>
<pre class="csharpcode">snake.Load(Content);</pre>
<p>Lastly for this test we'll just add a call to the snake's <i>Draw</i> method in our
<i>DrawInGame</i> method:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawInGame()
{
    orange.Draw(spriteBatch);
    snake.Draw(spriteBatch);
}</pre>
<p>Go ahead and run the game now and you should see the little snake in the top-left corner of the screen along with the orange that we added earlier:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_6.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_6.png" width="250" height="349"></a>
</p>
<p>There is already one issue with our game. The orange, as it keeps repositioning, occasionally will position itself underneath the snake. We want to avoid this at all costs. To accomplish this we need to add a new method to the Snake class called
<i>IsBodyOnPoint</i> which will tell us whether a given grid cell is occupied by one of the snake's body parts. To do this we simply leverage the list's
<i>Contains</i> method:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">bool</span> IsBodyOnPoint(Point p)
{
    <span class="kwrd">return</span> bodyPoints.Contains(p);
}</pre>
<p>Next we will modify the Orange class's <i>Reposition </i>method to take in a snake instance and use this to make sure we generate a random point not occupied by the snake:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Reposition(Snake snake)
{
    <span class="kwrd">do</span>
    {
        Position = <span class="kwrd">new</span> Point(rand.Next(Grid.MaxColumn), rand.Next(Grid.MaxRow));
    } <span class="kwrd">while</span> (snake.IsBodyOnPoint(Position));
}</pre>
<p>By using the do-while loop, we ensure that we will run that code at least once. Then if the position is found to be occupied by the snake, the code will continue looping until an unoccupied space has been found.
</p>
<p>Let's go ahead and update our code found in the Game1 <i>UpdateInGame</i> method to match this new method signature:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    <span class="kwrd">if</span> (gameTime.TotalGameTime.Milliseconds % 1000 == 0)
        orange.Reposition(snake);
}</pre>
<p>Now if you run the game, you'll notice the orange will never, ever position itself underneath of the snake. We now have enough of the core to begin working on making the snake move around. Let's head to the Snake class and add a few new methods:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Update(GameTime gameTime)
{ }

<span class="kwrd">private</span> <span class="kwrd">void</span> HandleInput()
{ }

<span class="kwrd">private</span> <span class="kwrd">void</span> MoveSnake()
{ }</pre>
<p>These three methods will handle all of our update code for the snake. First we'll start by filling in the main
<i>Update</i> method:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Update(GameTime gameTime)
{
    HandleInput();

    moveTimer &#43;= (<span class="kwrd">float</span>)gameTime.ElapsedGameTime.TotalSeconds;

    <span class="kwrd">if</span> (moveTimer &lt; MoveSpeed)
    {
        <span class="kwrd">return</span>;
    }

    moveTimer = 0f;
    currentDirection = nextDirection;
    MoveSnake();
}</pre>
<p>The first thing our method does is call the <i>HandleInput. </i>Next we add the elapsed time in seconds to our
<i>moveTimer</i> variable. Then we see if the <i>moveTimer</i> is less than the <i>
MoveSpeed</i> value. If <i>moveTimer</i> is less than the <i>MoveSpeed</i> we know that enough time has not elapsed so we call ‘return' to exit out of our update method. If
<i>moveTimer</i> has exceeded the <i>MoveSpeed</i> value, we proceed on with updating. The next thing we do is reset the
<i>moveTimer</i>. Then we assign the <i>nextDirection </i>as our <i>currentDirection</i> and call the
<i>MoveSnake</i> method.</p>
<p>We'll continue by filling in the <i>HandleInput</i> method:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> HandleInput()
{
    GamePadState gps = GamePad.GetState(PlayerIndex.One);

    <span class="kwrd">if</span> (gps.IsButtonDown(Buttons.DPadDown) &amp;&amp; currentDirection != Direction.Up)
    {
        nextDirection = Direction.Down;
    }
    <span class="kwrd">if</span> (gps.IsButtonDown(Buttons.DPadUp) &amp;&amp; currentDirection != Direction.Down)
    {
        nextDirection = Direction.Up;
    }
    <span class="kwrd">if</span> (gps.IsButtonDown(Buttons.DPadLeft) &amp;&amp; currentDirection != Direction.Right)
    {
        nextDirection = Direction.Left;
    }
    <span class="kwrd">if</span> (gps.IsButtonDown(Buttons.DPadRight) &amp;&amp; currentDirection != Direction.Left)
    {
        nextDirection = Direction.Right;
    }
}</pre>
<p>All we are doing here is finding out which DPad direction is down and using that for the next direction. We also check to make sure that the next direction is not the direct opposite of the current direction. Pretty simple.</p>
<p>Next is the <i>MoveSnake</i> method. This method takes care of two things for us. First it handles updating all the body points in the snake to move him around the grid. The second thing it handles is inserting new body pieces as requested. Let's take a
 look at the code:</p>
<pre class="csharpcode"> <span class="kwrd">private</span> <span class="kwrd">void</span> MoveSnake()
{
    Point p1 = bodyPoints[0];
    <span class="kwrd">switch</span> (currentDirection)
    {
        <span class="kwrd">case</span> Direction.Up:
            bodyPoints[0] = <span class="kwrd">new</span> Point(p1.X, p1.Y - 1);
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> Direction.Down:
            bodyPoints[0] = <span class="kwrd">new</span> Point(p1.X, p1.Y &#43; 1);
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> Direction.Left:
            bodyPoints[0] = <span class="kwrd">new</span> Point(p1.X - 1, p1.Y);
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> Direction.Right:
            bodyPoints[0] = <span class="kwrd">new</span> Point(p1.X &#43; 1, p1.Y);
            <span class="kwrd">break</span>;
    }
    <span class="kwrd">if</span> (extending)
    {
        bodyPoints.Insert(1, p1);
        extending = <span class="kwrd">false</span>;
        <span class="kwrd">return</span>;
    }
    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 1; i &lt; bodyPoints.Count; i&#43;&#43;)
    {
        Point p2 = bodyPoints[i];
        bodyPoints[i] = p1;
        p1 = p2;
    }
}</pre>
<p>Going through this little by little, what we first do is get the position of the head to store that for the next body part. We then use the
<i>currentDirection</i> value to move the head to the next position it should be at.</p>
<p>Following that we see if we need to add in a new body piece. If we need to, we simply insert the point the head used to be at into the list behind the head and exit the method since we have filled the gap left by moving our head.</p>
<p>If we did not extend, we then loop through all remaining body parts (including the tail) and update them by moving them to position of the body part in front of them.</p>
<p>We'll follow this up by again testing our code to make sure it all works. Head back to the Game1 class and update the
<i>UpdateInGame</i> method to call the snake's <i>Update</i> method:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    <span class="kwrd">if</span> (gameTime.TotalGameTime.Milliseconds % 1000 == 0)
        orange.Reposition(snake);
    snake.Update(gameTime);
}</pre>
<p>Now when you run the game your snake will take off towards the right. You can now use the DPad of your Xbox 360 controller (or Zune if you have deployed it there) to direct the snake around.</p>
<p>At this point we have all the ground work in place. Let's go ahead and make our gameplay actually goal oriented. First let's increase functionality that lets our snake eat the oranges. For us to do this, we need to be able to see if the snake's head is in
 the same grid cell as the orange. Our orange already has a position value, so we just need to add a method to see if the snake's head is at that position. We'll add the following method now to our Snake class:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">bool</span> IsHeadAtPosition(Point position)
{
    <span class="kwrd">return</span> (bodyPoints[0] == position);
}</pre>
<p>All this method does is compare the first point in our array to the position given and return if the two values are the same. With this in place, let's fix up the
<i>UpdateInGame</i> method to only reposition the orange when the snake eats it:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    snake.Update(gameTime);

    <span class="kwrd">if</span> (snake.IsHeadAtPosition(orange.Position))
        orange.Reposition(snake);
}</pre>
<p>Our orange is now updated appropriately so that it only repositions itself if eaten by the snake. However our snake still doesn't actually grow like he should. So we'll add another method to the Snake class that tells our snake to extend itself:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Extend()
{
    extending = <span class="kwrd">true</span>;
}</pre>
<p>We can now add this to our <i>UpdateInGame </i>method so that when the snake eats the orange, not only does the orange reposition itself, but the snake will also grow the next time it moves:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    snake.Update(gameTime);

    <span class="kwrd">if</span> (snake.IsHeadAtPosition(orange.Position))
    {
        orange.Reposition(snake);
        snake.Extend();
    }
}</pre>
<p>Now we're making some progress. We still have a big problem: there's no way to lose. In the original game of Snake you would lose by either crashing into the wall of the window or by making the snake crash into itself. We can address both of these cases
 by adding two methods to the Snake class:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">bool</span> IsLooped()
{
    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 1; i &lt; bodyPoints.Count; i&#43;&#43;)
        <span class="kwrd">if</span> (IsHeadAtPosition(bodyPoints[i]))
            <span class="kwrd">return</span> <span class="kwrd">true</span>;

    <span class="kwrd">return</span> <span class="kwrd">false</span>;
}

<span class="kwrd">public</span> <span class="kwrd">bool</span> IsHeadOffScreen()
{
    Point h = bodyPoints[0];
    <span class="kwrd">return</span> (h.X &lt; 0 || h.Y &lt; 0 || h.X &gt;= Grid.MaxColumn || h.Y &gt;= Grid.MaxRow);
}</pre>
<p>The first method, <i>IsLooped</i>, tests all body pieces against the head to see if the head is on the same space as them. The second method,
<i>IsHeadOffScreen</i>, checks to see if the head is out of the valid grid locations. Let's head back to the
<i>UpdateInGame</i> method and add in these tests:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    snake.Update(gameTime);

    <span class="kwrd">if</span> (snake.IsHeadAtPosition(orange.Position))
    {
        orange.Reposition(snake);
        snake.Extend();
    }

    <span class="kwrd">if</span> (snake.IsLooped())
        state = GameState.GameOver;

    <span class="kwrd">if</span> (snake.IsHeadOffScreen())
        state = GameState.GameOver;
}</pre>
<p>We now have the ability to lose the game which brings us very close to having a completed game. Let's now add some code to the start of the
<i>UpdateInGame</i> method to let the user exit back to the title screen by pressing the Back button.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateInGame(GameTime gameTime)
{
    <span class="kwrd">if</span> (IsNewButtonPress(Buttons.Back))
        state = GameState.Title;

    snake.Update(gameTime);

    <span class="kwrd">if</span> (snake.IsHeadAtPosition(orange.Position))
    {
        orange.Reposition(snake);
        snake.Extend();
    }

    <span class="kwrd">if</span> (snake.IsLooped())
        state = GameState.GameOver;

    <span class="kwrd">if</span> (snake.IsHeadOffScreen())
        state = GameState.GameOver;
}</pre>
<p>We are just about done with all of the code for the <i>UpdateInGame</i> method. Let's finish up by adding the ability to count the oranges that have been eaten. First we need to add a new integer variable to the Game1 class to hold the score:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">int</span> score;</pre>
<p>We now just increment the score every time the snake eats and orange. Inside of our
<i>UpdateInGame</i> method, update the code for the snake eating the orange to look like this:</p>
<pre class="csharpcode"><span class="kwrd">if</span> (snake.IsHeadAtPosition(orange.Position))
{
    orange.Reposition(snake);
    snake.Extend();
    score&#43;&#43;;
}</pre>
<p>We can now focus on finishing the drawing for the <i>DrawInGame</i>. All we need to do is display the current score on the screen. We'll start by adding a new string constant to the Game1 class:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> scoreFormat = <span class="str">&quot;Oranges Eaten: {0}&quot;</span>;</pre>
<p>The “{0}” in there, if you haven't worked with format strings before, is a placeholder that specifies where we want to insert our score.</p>
<p>Now let's head down to the <i>DrawInGame</i> method and add in the code to draw the score to our screen:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawInGame()
{
    orange.Draw(spriteBatch);
    snake.Draw(spriteBatch);
    DrawText(miniFont, <span class="kwrd">string</span>.Format(scoreFormat, score), <span class="kwrd">new</span> Vector2(120f, 5f));
}</pre>
<p>We can run the game and now see how well we're doing:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_7.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_7.png" width="250" height="349"></a>
</p>
<p>&nbsp;</p>
<p>We can now quickly fill in both the <i>UpdateGameOver</i> and <i>DrawGameOver</i> screens to simply display the results of the game and await input to return to the title screen. First we'll add two more string constants to the game:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> gameOver = <span class="str">&quot;Game Over!&quot;</span>;
<span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> gameOverInstructions = <span class="str">&quot;Press Play to Continue&quot;</span>;</pre>
<p>And then we can fill in the code for our two methods:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateGameOver()
{
    <span class="kwrd">if</span> (IsNewButtonPress(Buttons.B))
        state = GameState.Title;
}

<span class="kwrd">private</span> <span class="kwrd">void</span> DrawGameOver()
{
    orange.Draw(spriteBatch);
    snake.Draw(spriteBatch);

    DrawText(titleFont, gameOver, <span class="kwrd">new</span> Vector2(120f, 25f));
    DrawText(mediumFont, <span class="kwrd">string</span>.Format(scoreFormat, score), <span class="kwrd">new</span> Vector2(120f, 200f));
    DrawText(mediumFont, gameOverInstructions, <span class="kwrd">new</span> Vector2(120f, 225f));
}</pre>
<p>You can see that we not only draw text in our state, but we also draw the orange and snake. This lets the user see where things were when the game ended and is a nice touch to add to the game.</p>
<p>The last thing we add is the code to make sure that the <i>UpdateTitleScreen</i> method makes sure to reset the snake, orange, and score when the user starts a new game:</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateTitleScreen()
{
    <span class="kwrd">if</span> (IsNewButtonPress(Buttons.Back))
        Exit();

    <span class="kwrd">if</span> (IsNewButtonPress(Buttons.B))
    {
        snake.Reset();
        score = 0;
        orange.Reposition(snake);
        state = GameState.InGame;
    }
}</pre>
<p>And lastly we make sure the initial state is set to the title screen:</p>
<pre class="csharpcode"><span class="kwrd">private</span> GameState state = GameState.Title;</pre>
<p>With that your game is complete! You now have a fully functional Snake clone. “But what about the Zune?”, you ask. Let's take care of that right now.</p>
<p>XNA Game Studio has always aimed to be a cross-platform tool and the new Zune support is no exception. Getting our project onto a Zune is literally just a matter of clicks. First right click on your game project in the
<i>Solution Explorer</i> and choose the <i>Create Copy of Project for Zune</i> menu item. When completed you will have a complete duplicate project that targets the Zune platform. The
<i>Solution Explorer</i> should now look like this:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_8.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_8.png" width="271" height="428"></a>
</p>
<p>Next we need to build and deploy the game to the Zune. This process is also rather simple. If you went through the tutorial on the download instructions page, this will already be familiar to you. If not, we'll cover the whole process here.
</p>
<p>Head up to the <i>Tools</i> menu and choose the <i>Launch XNA Game Studio Device Center</i> option. You will be presented with a window that looks like this:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_9.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_9.png" width="500" height="329"></a>
</p>
<p>Click on the Add Device button and you will see the following dialog:</p>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_10.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_10.png" width="500" height="303"></a>
<p>&nbsp;</p>
<p>We want to add a Zune, so click on the Zune button. You should see your Zune appear in the window now:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_11.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_11.png" width="500" height="303"></a>
</p>
<p><i>Note: If your Zune did not appear in the window,make sure you have the latest Zune firmware on your device and that the Zune Player application is closed.
</i></p>
<p>From here select your Zune and press the Next button. After a brief moment you will see the success screen:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_12.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_12.png" width="500" height="303"></a>
</p>
<p>Press the Finish button and then close the XNA Game Studio Device Center.</p>
<p>Now click on the Zune project you created earlier and go up to the <i>Build</i> menu and click on
<i>Deploy Zune Copy of SammyTheSnake</i> to begin deploying the game to your Zune.</p>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_13.png"><img title="image" border="0" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8976852/image_thumb_13.png" width="267" height="262"></a>
<p>&nbsp;</p>
<p>You should see the Zune screen update to show that the game is deploying. Once the text on the screen changes to ”connected” or “waiting for computer”, your game has been completely deployed.</p>
<p>To get to the game on your Zune, simply press the center button to exit XNA Game Studio Connect. Next navigate in your main menu to find the Games option. Inside of there will you will see your newly deployed game. Simply click Play and away you go. Enjoy
 the new snake game and good luck on your adventures of Zune game development with XNA Game Studio.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:53b97e374aee4417a8499e7600ce34a1">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Sammy-The-Snake-An-XNA-game-for-the-Zune</comments>
      <itunes:summary>
Nick Gravelyn&amp;nbsp;- http://www.nickgravelyn.com/ 
Download: http://codeplex.com/sammythesnake

Software: Visual C# Express Editions,
XNA Game Studios 3.0 
Difficulty: Intermediate 
Time Required: 8 hours 
Cost: Free 
Artwork courtesy of George Clingerman of 
XNADevelopment.com 
Side note: XNA is c# only 
In the exciting world of XNA Game Studio, the new big thing is the XNA Game Studio 3.0 Beta. This beta allows developers to glimpse what will be coming with the full release of XNA Game Studio 3.0. One of the largest new features coming with XNA Game Studio
 3.0 is the new ability to create games for Microsoft&#39;s Zune media device. What we&#39;re going to cover today is how to create a full game for the Zune, specifically a clone of the classic “Snake” game. 
To begin you need to make sure you are set up to start working on Zune games. For all the details and instructions you will need for this step, please visit
http://creators.xna.com/en-us/3.0beta_mainpage. Once you have read and completed steps one and two, continue on with this tutorial. 
Welcome back! Now that you&#39;re all set up with XNA Game Studio 3.0 Beta, we can start working on our game. Since we want to test our game as we go forward, we&#39;re actually going to create the game as a Windows game first and then simply convert it to be a
 Zune project when we are finished. First open up Visual Studio 2008 or Visual C# 2008 Express and create a new Windows project. Let&#39;s call it “SammyTheSnake”. Choose the location to save the project and hit Ok. 
Now that we have the project created
 let&#39;s start out first by adding in the content for our game. George Clingerman of
XNADevelopment.com was nice enough to create some pretty graphics for this tutorial so those are the ones we are going to add to the project. In Visual Studio you will have a panel called the
Solution Explorer which will show you all of the files in your project. In that window you want to find the
Content node of your project. Right click on the Content</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Sammy-The-Snake-An-XNA-game-for-the-Zune</link>
      <pubDate>Mon, 06 Oct 2008 15:06:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Sammy-The-Snake-An-XNA-game-for-the-Zune</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8976852_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8976852_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Nick Gravelyn </dc:creator>
      <itunes:author>Nick Gravelyn </itunes:author>
      <slash:comments>18</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Sammy-The-Snake-An-XNA-game-for-the-Zune/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Great new games coming your way from XBOX Live arcade</title>
      <description><![CDATA[You may not have heard of them, but <a href="http://www.chairentertainment.com/">Chair Entertainment</a>&nbsp;has been bringing you great games for years now. Perhaps you've played&nbsp;<a href="http://www.chairentertainment.com/company/projects/undertow">Undertow</a>&nbsp;on XBOX Live arcade? If not, you should- especially since it was just named XBLA Game of the Year by Official Xbox Magazine.&nbsp; And there's&nbsp;more good news! The expansion pack, &quot;Path of the Elect&quot; was just released. The BIG NEWS though, is about&nbsp;Chair Entertainment's next big thing: <a href="http://www.chairentertainment.com/company/projects">Empire</a>. They decided to kick off their franchise by commissioning a book, Empire, written by Orson Scott Card. If you're not convinced yet that Chair is a company that should be on your radar, then watch this clip to learn about them also&nbsp;acquiring the interactive rights to Orson Scott Card's : <a href="http://en.wikipedia.org/wiki/Ender's_Game">Enders Game</a>. And a few other juicy surprises as well..... <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:a1f5fb629fb345558c5b9e0f01007c18">]]></description>
      <comments>http://channel9.msdn.com/Blogs/LauraFoy/Undertow</comments>
      <itunes:summary>You may not have heard of them, but Chair Entertainment&amp;nbsp;has been bringing you great games for years now. Perhaps you&#39;ve played&amp;nbsp;Undertow&amp;nbsp;on XBOX Live arcade? If not, you should- especially since it was just named XBLA Game of the Year by Official Xbox Magazine.&amp;nbsp; And there&#39;s&amp;nbsp;more good news! The expansion pack, &amp;quot;Path of the Elect&amp;quot; was just released. The BIG NEWS though, is about&amp;nbsp;Chair Entertainment&#39;s next big thing: Empire. They decided to kick off their franchise by commissioning a book, Empire, written by Orson Scott Card. If you&#39;re not convinced yet that Chair is a company that should be on your radar, then watch this clip to learn about them also&amp;nbsp;acquiring the interactive rights to Orson Scott Card&#39;s : Enders Game. And a few other juicy surprises as well.....</itunes:summary>
      <itunes:duration>795</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/LauraFoy/Undertow</link>
      <pubDate>Tue, 18 Mar 2008 19:55:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/LauraFoy/Undertow</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_92916476-17b0-4ba4-9838-adcd685449b8.jpg" height="0" width="0"></media:thumbnail>
      <media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_small_on10.jpg" height="64" width="85"></media:thumbnail>
      <media:group>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_2MB_on10.wmv" expression="full" duration="795" fileSize="229754393" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_on10.mp3" expression="full" duration="795" fileSize="6361466" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_on10.mp4" expression="full" duration="795" fileSize="41191809" type="video/mp4" medium="video"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_on10.wma" expression="full" duration="795" fileSize="6436639" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_on10.wmv" expression="full" duration="795" fileSize="46201915" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_Zune_on10.wmv" expression="full" duration="795" fileSize="63050295" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="mms://mschnlnine.wmod.llnwd.net/a1809/d1/on10/4/3/6/1/2/Undertow_s_on10.wmv" expression="full" duration="795" fileSize="197" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://mschnlnine.vo.llnwd.net/d1/on10/4/3/6/1/2/Undertow_on10.wmv" length="46201915" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Laura Foy</dc:creator>
      <itunes:author>Laura Foy</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/LauraFoy/Undertow/RSS</wfw:commentRss>
      <category>downloads</category>
      <category>Xbox</category>
      <category>Xbox Live</category>
      <category>Video Games</category>
      <category>arcade</category>
      <category>undertow</category>
      <category>chair entertainment</category>
      <category>download</category>
    </item>
  <item>
      <title>Xbox 360 Arcade Launched</title>
      <description><![CDATA[The Xbox 360 Arcade has now launched, making the popular gaming console a more family-friendly and affordable system. The new system features a wireless controller, an HDMI connection for high-def output, 256 MB of memory for storing games, and 5 games. The included games are: &quot;PAC-MAN Championship Edition,&quot; &quot;Uno,&quot; &quot;Luxor 2&quot;, &quot;Boom Boom Rocket&quot;, and &quot;Feeding Frenzy&quot;. At $279.99, the low priced offering that plays games, TV shows, and music is sure to be very appealing to families as an all-in-one device. The Arcade's Family Settings feature also brings peace of mind to mom &amp; dad, by allowing them to control the kind of content their kids watch and play. In addition the announcement of the console, also announced were the addition of more kid-friendly content for the Xbox: “Looney Tunes” cartoons, Nickelodeon's “Blue’s Clues,” “The Backyardigans” and “iCarly.&quot; Also, “SpongeBob SquarePants Underpants Slam&quot; and “SHREK-N-ROLL&quot; games will also be available exclusively on Xbox LIVE Arcade. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:747acd0c3d0f496190d49e0d00e0e093">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/Xbox-360-Arcade-Launched</comments>
      <itunes:summary>The Xbox 360 Arcade has now launched, making the popular gaming console a more family-friendly and affordable system. The new system features a wireless controller, an HDMI connection for high-def output, 256 MB of memory for storing games, and 5 games. The included games are: &amp;quot;PAC-MAN Championship Edition,&amp;quot; &amp;quot;Uno,&amp;quot; &amp;quot;Luxor 2&amp;quot;, &amp;quot;Boom Boom Rocket&amp;quot;, and &amp;quot;Feeding Frenzy&amp;quot;. At $279.99, the low priced offering that plays games, TV shows, and music is sure to be very appealing to families as an all-in-one device. The Arcade&#39;s Family Settings feature also brings peace of mind to mom &amp;amp; dad, by allowing them to control the kind of content their kids watch and play. In addition the announcement of the console, also announced were the addition of more kid-friendly content for the Xbox: “Looney Tunes” cartoons, Nickelodeon&#39;s “Blue’s Clues,” “The Backyardigans” and “iCarly.&amp;quot; Also, “SpongeBob SquarePants Underpants Slam&amp;quot; and “SHREK-N-ROLL&amp;quot; games will also be available exclusively on Xbox LIVE Arcade.</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/Xbox-360-Arcade-Launched</link>
      <pubDate>Fri, 02 Nov 2007 18:04:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/Xbox-360-Arcade-Launched</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/blogs/arcade.jpg" height="240" width="320"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/previewsmall/19482.jpg" height="64" width="85"></media:thumbnail>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/Xbox-360-Arcade-Launched/RSS</wfw:commentRss>
      <category>Xbox 360</category>
      <category>arcade</category>
    </item>
  <item>
      <title>YeahTrivia: Creating a Trivia Server/Client with WPF and WCF</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50"><img height="50" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/yeahtriviathumb.gif" width="50"></td>
<td class=""><span class="entry_description">In this article I'll take you along for the ride as I attack the learning curve required to create a fun, interactive application using both the Microsoft Windows Presentation Foundation (WPF) and the Windows Communication
 Foundation (WCF). Afterwards, you'll have a flexible trivia client/server game ready to play by yourself or against friends, coworkers and your local know-it-all.&nbsp;
<em>And in honor of Halloween, I've included three games of horror movie trivia.</em></span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Steve Holstad</div>
<div class="entry_company"><a href="http://blogs.claritycon.com/blogs/steve_holstad/archive/2007/10/29/3403.aspx" target="_blank">The Bright Lights</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Advanced</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
6-10 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input">Visual Studio Express, 2005, 2008 Beta 2
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&amp;displaylang=en">
Microsoft .NET Framework 3.0</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a class="" href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/YeahTrivia.zip" target="_blank">Download Source</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>&nbsp;</p>
<h3>What can YeahTrivia do for me?</h3>
<p>Glad you asked. This project started when I decided I wanted to dive headfirst into learning WPF and WCF, without hacking through countless Hello World examples.&nbsp; And I wanted something fun that I could improve over time as my skills developed in these new
 technologies.&nbsp; In this article I'll take you along for the ride as I attack the learning curve required to create a fun, interactive application using both the Microsoft Windows Presentation Foundation (WPF) and the Windows Communication Foundation (WCF).
 Afterwards, you'll have a flexible trivia client/server game ready to play by yourself or against friends, coworkers and your local know-it-all.&nbsp; And in honor of Halloween, I've included three games of horror movie trivia.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/YeahTrivia_Client5.jpg"><img height="194" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/YeahTrivia_Client_thumb1.jpg" width="280" border="0"></a>
</p>
<p>In case you were wondering, the &quot;YeahTrivia&quot; name honors my new bride&nbsp;&amp; her&nbsp;favorite prefix.&nbsp; Think of it as&nbsp;YeeeeaaaaahhTrivia!</p>
<h3>Basic Setup</h3>
<p>This demo project was built using Visual Studio 2008 Beta 2, and is based on the Microsoft .NET Framework version 3.0.&nbsp; The game is fed by a small windows app that acts as a game server, providing game selection, user&nbsp;registration, question loading, response
 times, chat messaging&nbsp;and scorekeeping.&nbsp; The server loads a game by reading a predefined XML format, which we will look at a bit later.&nbsp; This dynamic load lets anyone create their own flavor of trivia game, with any number of questions.</p>
<p>The server app exposes one WCF endpoint, a wsDualHttpBinding channel that supports duplex (two-way) communication between the server and any number of game clients.&nbsp; Clients attach themselves to this endpoint and provide a callback address to the server.&nbsp;
 The server saves an instance of this callback channel and uses each client's instance to&nbsp;contact the clients en masse during general game flow.&nbsp; Enough talk, here's how to build one yourself.</p>
<h3>Trivia Common and WCF Service Interfaces</h3>
<p>The TriviaCommon project provides both the server and client projects access to shared objects.&nbsp; To keep things simple the Common project only contains two classes:</p>
<p>Constants.cs defines the AnswerItem enumeration, which gives easy access to the five answer options (None, A, B, C, D), and the QuestionItem struct.&nbsp; This structure is delivered to the client and contains question text, answer text, and the correct answer
 object of type AnswerItem.&nbsp; Notice that objects being directly passed over the wire need to be marked with the [DataContract] attribute.</p>
<p>The second class, Interfaces.cs is where our WCF fun begins.&nbsp; Take a look:</p>
<strong>C#:</strong><br>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.ServiceModel;
<span class="kwrd">using</span> System.Text;

<span class="kwrd">namespace</span> Trivia.Common
{
    <span class="preproc">#region</span> Interfaces

    <span class="preproc">#region</span> Service Interface

    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// Interface that defines Trivia service contract.</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    [ServiceContract(CallbackContract = <span class="kwrd">typeof</span>(ITriviaCallback))]
    <span class="kwrd">public</span> <span class="kwrd">interface</span> ITrivia
    {
        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> RegisterUser(<span class="kwrd">string</span> userName);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> AcceptAnswer(<span class="kwrd">string</span> userName, <span class="kwrd">string</span> answerValue);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> ChatPublish(<span class="kwrd">string</span> userName, <span class="kwrd">string</span> message);
    }

    <span class="preproc">#endregion</span> Service Interface

    <span class="preproc">#region</span> Client Callback Interface

    <span class="rem">/// &lt;summary&gt;</span>
    <span class="rem">/// Interface that defines Trivia client callback contract.</span>
    <span class="rem">/// &lt;/summary&gt;</span>
    <span class="kwrd">public</span> <span class="kwrd">interface</span> ITriviaCallback
    {        
        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnGameStart(<span class="kwrd">int</span> questionCount);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnGameEnd();

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnUserRegistered(<span class="kwrd">string</span> userName);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnPublishChat(<span class="kwrd">string</span> userName, <span class="kwrd">string</span> chatMessage);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnQuestionLoad(<span class="kwrd">int</span> questionIndex, QuestionItem questionItem);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnQuestionEnd();

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnQuestionStatusUpdate(Int64 questionTimeRemaining);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnScoreboardUpdate(Dictionary&lt;<span class="kwrd">string</span>, Int64&gt; scoreboard);

        [OperationContract(IsOneWay = <span class="kwrd">true</span>)]
        <span class="kwrd">void</span> OnGameServerStopped();
    }

    <span class="preproc">#endregion</span> Client Callback Interface

    <span class="preproc">#endregion</span> Interfaces
}
</pre>
<pre class="csharpcode"></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>VB:</strong></p>
<pre class="csharpcode"><span class="kwrd">Imports</span> System
<span class="kwrd">Imports</span> System.Collections.Generic
<span class="kwrd">Imports</span> System.ServiceModel
<span class="kwrd">Imports</span> System.Text

<span class="kwrd">Namespace</span> Trivia.Common

<span class="preproc">#Region</span> <span class="str">&quot;Interfaces&quot;</span>

<span class="preproc">#Region</span> <span class="str">&quot;Service Interface&quot;</span>
    
    <span class="rem">''' &lt;summary&gt;</span>
    <span class="rem">''' Interface that defines Trivia service contract.</span>
    <span class="rem">''' &lt;/summary&gt;</span>
    &lt;ServiceContract(CallbackContract:=<span class="kwrd">GetType</span>(ITriviaCallback))&gt; _
    <span class="kwrd">Public</span> <span class="kwrd">Interface</span> ITrivia
        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> RegisterUser(<span class="kwrd">ByVal</span> userName <span class="kwrd">As</span> <span class="kwrd">String</span>)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> AcceptAnswer(<span class="kwrd">ByVal</span> userName <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> answerValue <span class="kwrd">As</span> <span class="kwrd">String</span>)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> ChatPublish(<span class="kwrd">ByVal</span> userName <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> message <span class="kwrd">As</span> <span class="kwrd">String</span>)
    <span class="kwrd">End</span> <span class="kwrd">Interface</span>
        
<span class="preproc">#End Region</span>

<span class="preproc">#Region</span> <span class="str">&quot;Client Callback Interface&quot;</span>

    <span class="rem">''' &lt;summary&gt;</span>
    <span class="rem">''' Interface that defines Trivia client callback contract.</span>
    <span class="rem">''' &lt;/summary&gt;</span>
    <span class="rem">''' &lt;remarks&gt;&lt;/remarks&gt;</span>
    <span class="kwrd">Public</span> <span class="kwrd">Interface</span> ITriviaCallback
        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
      <span class="kwrd">Sub</span> OnGameStart(<span class="kwrd">ByVal</span> questionCount <span class="kwrd">As</span> <span class="kwrd">Integer</span>)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnGameEnd()

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnUserRegistered(<span class="kwrd">ByVal</span> userName <span class="kwrd">As</span> <span class="kwrd">String</span>)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnPublishChat(<span class="kwrd">ByVal</span> userName <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> chatMessage <span class="kwrd">As</span> <span class="kwrd">String</span>)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnQuestionLoad(<span class="kwrd">ByVal</span> questionIndex <span class="kwrd">As</span> <span class="kwrd">Integer</span>, <span class="kwrd">ByVal</span> questionItem <span class="kwrd">As</span> QuestionItem)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnQuestionEnd()

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnQuestionStatusUpdate(<span class="kwrd">ByVal</span> questionTimeRemaining <span class="kwrd">As</span> <span class="kwrd">Long</span>)

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnScoreboardUpdate(<span class="kwrd">ByVal</span> scoreboard <span class="kwrd">As</span> Dictionary(Of <span class="kwrd">String</span>, <span class="kwrd">Long</span>))

        &lt;OperationContract(IsOneWay:=<span class="kwrd">True</span>)&gt; _
        <span class="kwrd">Sub</span> OnGameServerStopped()

    <span class="kwrd">End</span> <span class="kwrd">Interface</span>

<span class="preproc">#End Region</span>

<span class="preproc">#End Region</span>

<span class="kwrd">End</span> <span class="kwrd">Namespace</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>A few items of interest here.&nbsp; Notice we're importing the System.ServiceModel namespace.&nbsp; This is the key assembly when using WCF, so don't forget to add a reference to your project.&nbsp; The first interface, ITrivia, defines the operations the server is required
 to implement, which handle basic user actions: Register a team, accept an answer and accept a chat message.&nbsp; Easy.</p>
<p>The second interface, cleverly named ITriviaCallback, lays out the callback contract a client must fulfill in order to play nicely with our server.&nbsp; The operations listed here describe events the server will publish.&nbsp; These aren't actual events, but the
 naming convention &quot;OnX...&quot; helps you remember that these are server published activities.</p>
<p>Notice that the [OperationContract] attribute notifies WCF that each method is part of a service contract.&nbsp; The IsOneWay flag gives us &quot;fire-and-forget&quot; behavior (the app shouldn't wait around for a response).&nbsp; So now that the common objects are ready, let's
 move on to...</p>
<h3>Building the Trivia Server</h3>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/YeahTrivia_Server1.jpg"><img height="202" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/YeahTrivia_Server.jpg" width="240" border="0"></a>
</p>
<p>The YeahTrivia Server is a simple utility app, but don't let&nbsp;the plain looks fool you; I thought about calling this the BrainStumper Pumper, but this is a family site.&nbsp; This app&nbsp;lets a user (anyone acting as game admin)&nbsp;start the service, select the desired
 game, await team registrations, and then start the game.&nbsp; If this were to become a larger scale project, I would make this an IIS hosted service that manages multiple games and provides more autonomy.&nbsp; Until those sports bar royalty checks start rolling in,
 however, a utility app will do just fine.</p>
<p>The only form, GameServerDashboard, simply provides user interaction with the GameServer class.&nbsp; On startup, the form&nbsp;inits an instance of GameServer and tells it to start the service.&nbsp; It also loads all trivia question sets from the Games directory, and
 displays them in the list.</p>
<p>GameServer is the brain behind YeahTrivia.&nbsp;The attributes below set up the GameServer for action:</p>
<p><strong>C#:</strong><br>
</p>
<pre class="csharpcode">[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant
        ,InstanceContextMode = InstanceContextMode.Single)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> GameServer : ITrivia</pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p><strong>VB:</strong><br>
</p>
<pre class="csharpcode">&lt;ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Reentrant, InstanceContextMode:=InstanceContextMode.<span class="kwrd">Single</span>)&gt; _
    <span class="kwrd">Public</span> <span class="kwrd">Class</span> GameServer
        <span class="kwrd">Implements</span> ITrivia</pre>
<pre class="csharpcode"></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>ConcurrencyMode.Reentrant prevents deadlocks between the&nbsp;apps&nbsp;by stating that while this service is single-threaded, callbacks are allowed to invoke&nbsp;new&nbsp;operations.</p>
<p>InstanceContextMode.Single sets the service as a singleton, so that all messages are delivered to the same object instance.</p>
<p>These are advanced topics if you're new to WCF, so I'll include some links at the end that helped clarify some of this for me.&nbsp; Let's keep moving forward by looking at a few activities of the game server:</p>
<p><em>Start the Service:</em>&nbsp; Passes in the configured base address as a Uri, inits and opens a new ServiceHost.</p>
<p><strong>C#:</strong></p>
<blockquote>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> StartService()
{
<span class="rem">   // Set base address and open service host</span>
   Uri baseAddress = <span class="kwrd">new</span> Uri(ConfigurationManager.AppSettings[CONFIG_KEY_BASEURI]);
   _serviceHost = <span class="kwrd">new</span> ServiceHost(<span class="kwrd">new</span> GameServer(), baseAddress);
   _serviceHost.Open();
}</pre>
</blockquote>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>VB:</strong></p>
<pre class="csharpcode">  <span class="kwrd">Public</span> <span class="kwrd">Sub</span> StartService()
     <span class="rem">'Set base address and open service host</span>
     <span class="kwrd">Dim</span> baseAddress <span class="kwrd">As</span> <span class="kwrd">New</span> Uri(ConfigurationManager.AppSettings(CONFIG_KEY_BASEURI))
     _serviceHost = <span class="kwrd">New</span> ServiceHost(<span class="kwrd">New</span> GameServer(), baseAddress)
     _serviceHost.Open()
  <span class="kwrd">End Sub</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><em></em>&nbsp;</p>
<p><em>Register a new team:</em>&nbsp;Saves off the callback, adds it to the callback collection and scoreboard containers, notifies the user of a successful registration, and notifies all game clients of the new team.</p>
<p><strong>C#:</strong></p>
<pre class="csharpcode"> <span class="kwrd">public</span> <span class="kwrd">void</span> RegisterUser(<span class="kwrd">string</span> userName)
 {
     _currentCallback = OperationContext.Current.GetCallbackChannel&lt;ITriviaCallback&gt;();

     <span class="rem">// Store callback</span>
     <span class="kwrd">if</span> (!_callbacks.ContainsKey(userName))
     {
         _callbacks.Add(userName, _currentCallback);
         _scoreboard.Add(userName, 0);
</pre>
<pre class="csharpcode">         <span class="rem">// Notify user of registration</span>
         _currentCallback.OnUserRegistered(userName);
</pre>
<pre class="csharpcode">         <span class="rem">// Notify clients of new user</span>
         <span class="kwrd">foreach</span> (<span class="kwrd">string</span> userKey <span class="kwrd">in</span> _callbacks.Keys)
         {
            _currentCallback = _callbacks[userKey];
            _currentCallback.OnPublishChat(GAME_USERKEY, <span class="kwrd">string</span>.Format(FORMAT_USER_REGISTERED, userName));
         }                
     }
     <span class="kwrd">else</span>
     {
         <span class="rem">// User already registered, throw exception</span>
         <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(ERROR_USER_ALREADY_EXISTS);
     }
 }</pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>VB:</strong></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> RegisterUser(<span class="kwrd">ByVal</span> userName <span class="kwrd">As</span> <span class="kwrd">String</span>) <span class="kwrd">Implements</span> ITrivia.RegisterUser
   _currentCallback = OperationContext.Current.GetCallbackChannel(Of ITriviaCallback)()

   <span class="rem">'Store callback</span>
   <span class="kwrd">If</span> <span class="kwrd">Not</span> _callbacks.ContainsKey(userName) <span class="kwrd">Then</span>
      _callbacks.Add(userName, _currentCallback)
      _scoreboard.Add(userName, 0)

      <span class="rem">'Notify user of registration</span>
      _currentCallback.OnUserRegistered(userName)

      <span class="rem">'Notify clients of new user</span>
      <span class="kwrd">For</span> <span class="kwrd">Each</span> userKey <span class="kwrd">As</span> <span class="kwrd">String</span> <span class="kwrd">In</span> _callbacks.Keys
         _currentCallback = _callbacks(userKey)
         _currentCallback.OnPublishChat(GAME_USERKEY, <span class="kwrd">String</span>.Format(FORMAT_USER_REGISTERED, userName))
      <span class="kwrd">Next</span>
   <span class="kwrd">Else</span>
      <span class="rem">'User already registered, throw exception</span>
      <span class="kwrd">Throw</span> <span class="kwrd">New</span> Exception(ERROR_USER_ALREADY_EXISTS)
   <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End Sub</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can start to see how the server is able to handle incoming calls and process them back to the clients using the duplex channel.&nbsp; I'll leave the rest of the server actions for you to examine on your own.</p>
<h3>Building the Game Client (WCF) </h3>
<p>Address, Binding, Contract.&nbsp; These are the ABC's of WCF.&nbsp; The client's app.config file handles connecting to the service and specifying the channel and contract used to interact with it.&nbsp; Examine the client portion of the client .config:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">client</span><span class="kwrd">&gt;</span>
   <span class="kwrd">&lt;</span><span class="html">endpoint</span> <span class="attr">address</span><span class="kwrd">=&quot;http://localhost:8088/Trivia&quot;</span> <span class="attr">binding</span><span class="kwrd">=&quot;wsDualHttpBinding&quot;</span>
      <span class="attr">bindingConfiguration</span><span class="kwrd">=&quot;WSDualHttpBinding_ITrivia&quot;</span> <span class="attr">contract</span><span class="kwrd">=&quot;Trivia.Common.ITrivia&quot;</span>
      <span class="attr">name</span><span class="kwrd">=&quot;WSDualHttpBinding_ITrivia&quot;</span><span class="kwrd">&gt;</span>
   <span class="kwrd">&lt;/</span><span class="html">endpoint</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">client</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The address points to the exposed service endpoint.&nbsp; The binding sets the channel as &quot;wsDualHttpBinding&quot; (our http duplex channel).&nbsp; The bindingConfiguration attribute is an optional&nbsp;pointer to another group of configurations for the binding, and finally,
 the contract sets the interface with which our client will be interacting.</p>
<p>Next it's time to generate a proxy class.&nbsp;&nbsp;Memorize this: Svcutil.exe is your friend.&nbsp; The client needs a proxy class that it can use to interact with the service model.&nbsp; The&nbsp;utility is a bit tricky at first, because of the wealth of optional flags, but
 stick with it, it's better than coding the proxy class by hand!&nbsp; You can generate your client code by starting the service and running a command line similar to this:</p>
<pre class="csharpcode">svcutil /language:cs /out:ServerProxy.cs <a href="http://localhost:8088/Trivia">http://localhost:8088/Trivia</a></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Add the generated class to the client project and you can begin to interact with the service.&nbsp; The svcutil is available as part of the Windows SDK.&nbsp; Check out the referenced site below&nbsp;for more information on this handy utility.</p>
<h3>Building the Game Client (WPF)</h3>
<p>Building the WPF portion of the client app was really a learning experience, and it will&nbsp;be the&nbsp;priority for me to improve in a later version.&nbsp; Learning to program in XAML markup can seem daunting, and it requires a large paradigm shift on your part in order
 to grasp the new concepts.&nbsp;&nbsp;Microsoft Expression is powerful tool for XAML work, but this time I coded all of the XAML by hand in order to fully see what was taking place inside.</p>
<p>A deep discussion of WPF is beyond the scope of this article, but take a look at the example code to get an idea of the layout.&nbsp; An excellent book to start with is
<u>WPF Unleashed</u> by Adam Nathan.&nbsp; An easy read (for a programming book), and solid examples to get you rolling.</p>
<p>I've set up the client using&nbsp;a instance of the Window class, which is shown below:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Window</span> <span class="attr">x:Class</span><span class="kwrd">=&quot;Trivia.Client.GameClient&quot;</span>
    <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span class="attr">Title</span><span class="kwrd">=&quot;YeahTrivia&quot;</span> <span class="attr">MinHeight</span><span class="kwrd">=&quot;620&quot;</span> <span class="attr">MinWidth</span><span class="kwrd">=&quot;620&quot;</span> 
    <span class="attr">WindowStartupLocation</span><span class="kwrd">=&quot;CenterScreen&quot;</span> <span class="attr">WindowState</span><span class="kwrd">=&quot;Normal&quot;</span>  <span class="attr">Style</span><span class="kwrd">=&quot;{DynamicResource MainWindowStyle}&quot;</span>
    <span class="attr">Background</span><span class="kwrd">=&quot;{DynamicResource MainWindowBackgroundBrush}&quot;</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The window class sets up the outermost container of the app, and includes two default namespaces.&nbsp; I've also set a few other properties here: a min height and width, window startup location &amp; state, and two styling attributes set by dynamic resources.</p>
<p>Resources are a great way to further separate form &amp; function, allowing a programmer to handle the behavior of an app, while a designer can work simultaneously on the look, all without stepping on too many toes.&nbsp; As a 2.0 task for this project, I would remove
 all inline styling and move them into resource dictionaries.&nbsp; A dictionary contains styles and control templates (a skin) that can be loaded &amp; switched&nbsp;at runtime.</p>
<p>ResourceDictionaries are linked to your XAML in the App.Xaml file.&nbsp; Once you've set up the reference, the&nbsp;example above show&nbsp;how to&nbsp;reference the current dictionary:&nbsp; The Background and Style&nbsp;properties are set as dynamic resources by naming&nbsp;the Keys specified
 in the&nbsp;ResourceDictionary (DefaultResources.xaml):</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">LinearGradientBrush</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;MainWindowBackgroundBrush&quot;</span> <span class="attr">StartPoint</span><span class="kwrd">=&quot;.45,.45&quot;</span> <span class="attr">EndPoint</span><span class="kwrd">=&quot;.55,.55&quot;</span> <span class="attr">SpreadMethod</span><span class="kwrd">=&quot;Reflect&quot;</span><span class="kwrd">&gt;</span>
   <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Offset</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">Color</span><span class="kwrd">=&quot;DodgerBlue&quot;</span><span class="kwrd">/&gt;</span>
   <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Offset</span><span class="kwrd">=&quot;.8&quot;</span> <span class="attr">Color</span><span class="kwrd">=&quot;DarkSlateBlue&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;{x:Type Window}&quot;</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;MainWindowStyle&quot;</span><span class="kwrd">&gt;</span>
   <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;FontFamily&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Trebuchet MS&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Not quite as easy as CSS, but for a Forms project, it's a nice feature.&nbsp; The sample ResourceDictionary includes a button control template for all of my buttons, based on Rob Eisenberg's excellent article (link below).</p>
<p>One other interesting feature to point out: Take a look at the code-behind class MarshalToUIThread method, which accepts a SendOrPostCallback parameter.&nbsp; This is where&nbsp;the client is transferring actions from the sync thread back to the UI thread.&nbsp; In each
 interface method implementation (OnX..), you can see how I wrap any UI-directed code and assign&nbsp;it to the postCallback field.&nbsp; Passing this to the MarshalToUIThread method simply issues a SynchronizationContext.Post call, and the UI thread executes as expected.</p>
<h3>Creating a New Trivia Game (XML)</h3>
<p>New trivia games can be added at any time using&nbsp;the simple XML format shown here.&nbsp; After installing the server application, simply drop the new .XML file into the Games directory ([Server Install Location]\Yeah Trivia Server\Games).&nbsp; This demo comes pre-loaded
 with Geek Trivia, and&nbsp;a special Halloween Trivia version in case you're feeling festive.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">TriviaQuestionDataSet</span> <span class="attr">xmlns</span><span class="kwrd">=&quot;http://tempuri.org/TriviaQuestionDataSet.xsd&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TriviaQuestion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">QuestionText</span><span class="kwrd">&gt;</span>Name the highest grossing Monty Python creation.<span class="kwrd">&lt;/</span><span class="html">QuestionText</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextA</span><span class="kwrd">&gt;</span>A) Holy Grail<span class="kwrd">&lt;/</span><span class="html">AnswerTextA</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextB</span><span class="kwrd">&gt;</span>B) The Life of Brian<span class="kwrd">&lt;/</span><span class="html">AnswerTextB</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextC</span><span class="kwrd">&gt;</span>C) Shrubbery<span class="kwrd">&lt;/</span><span class="html">AnswerTextC</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextD</span><span class="kwrd">&gt;</span>D) The Meaning of Life<span class="kwrd">&lt;/</span><span class="html">AnswerTextD</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">CorrectAnswerKey</span><span class="kwrd">&gt;</span>A<span class="kwrd">&lt;/</span><span class="html">CorrectAnswerKey</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">TriviaQuestion</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TriviaQuestion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">QuestionText</span><span class="kwrd">&gt;</span>Ferris Bueller's best friend was _________.<span class="kwrd">&lt;/</span><span class="html">QuestionText</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextA</span><span class="kwrd">&gt;</span>A) Sloane Peterson<span class="kwrd">&lt;/</span><span class="html">AnswerTextA</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextB</span><span class="kwrd">&gt;</span>B) Edward R. Rooney<span class="kwrd">&lt;/</span><span class="html">AnswerTextB</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextC</span><span class="kwrd">&gt;</span>C) Charlie Sheen<span class="kwrd">&lt;/</span><span class="html">AnswerTextC</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AnswerTextD</span><span class="kwrd">&gt;</span>D) Cameron Frye<span class="kwrd">&lt;/</span><span class="html">AnswerTextD</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">CorrectAnswerKey</span><span class="kwrd">&gt;</span>D<span class="kwrd">&lt;/</span><span class="html">CorrectAnswerKey</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">TriviaQuestion</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">TriviaQuestionDataSet</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h3>It's Time to Play YeahTrivia</h3>
<p>Install both the Server and Client applications.&nbsp; First, fire up the server, and then start your game client(s).&nbsp; Once everyone has registered a team, select your game and hit &quot;Start Game&quot;.&nbsp;&nbsp;&nbsp; You're off...</p>
<h3>Game Over</h3>
<p>So there you have it.&nbsp; We've seen&nbsp;how WCF manages communication between objects, extracting complicated service protocols away from your code.&nbsp; And just a&nbsp;small subset of the WPF functionality has shown us&nbsp;how quickly a rich, XAML-based UI can come together.&nbsp;
 And maybe, just maybe, you've learned why a CD is 74 minutes long... but I'm not telling.</p>
<p>I challenge you to improve on this initial version of YeahTrivia:&nbsp; Crack open the XAML and add animations, images, video, music &amp; more.&nbsp;&nbsp;Create a self-maintaining server to run multiple games at once.&nbsp; Add a High Score storage system.&nbsp; Extend the WCF settings
 to enable other communication channels.&nbsp; Add a new skin.&nbsp;Create new question files to share with us.&nbsp;&nbsp;Whatever you do, have fun and&nbsp;go nuts.&nbsp; YeahCoding4Fun.</p>
<p>Download <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5773166/YeahTrivia.zip">
source files</a></p>
<p>Download <a href="http://employees.claritycon.com/sholstad/blog/Coding4Fun/YeahTrivia/">
compiled demo (C# and VB)</a></p>
<h3>About The Author</h3>
<p>Steve Holstad works as a software consultant for Clarity Consulting in Chicago.&nbsp; He blogs at
<a href="http://blogs.claritycon.com/blogs/steve_holstad/default.aspx" target="_blank">
The Bright Lights</a>, and is available via email at <a href="mailto:sholstad@claritycon.com">
sholstad@claritycon.com</a></p>
<p>&nbsp;</p>
<h3>References</h3>
<p><a href="http://wcf.netfx3.com/" target="_blank">wcf.netfx3.com/</a><br>
<a href="http://wpf.netfx3.com/" target="_blank">wpf.netfx3.com/</a><br>
<a href="http://msdn2.microsoft.com/en-us/library/ms733133.aspx" target="_blank">Generating a client proxy class</a><br>
<a href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.concurrencymode.aspx" target="_blank">ConcurrencyMode</a><br>
<a href="http://msdn2.microsoft.com/en-us/library/ms733133.aspx">SvcUtil.exe Tutorial</a>
<br>
<a href="http://devlicio.us/blogs/rob_eisenberg/archive/2006/12/03/net-3-0-crash-course-part-6-wpf-styles-and-control-templates.aspx" target="_blank">Rob Eisenberg's WPF control template</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><em>Special thanks to <a href="https://blogs.claritycon.com/blogs/bryan_dougherty/default.aspx" target="_blank">
Bryan Dougherty</a> for the WCF jumpstart, <a href="https://blogs.claritycon.com/blogs/kevin_marshall/default.aspx" target="_blank">
Kevin Marshall</a> for the Halloween Trivia and <a href="http://blogs.techrepublic.com.com/geekend/index.php?cat=400&amp;submit=view" target="_blank">
Jay Garmon</a>, creator of TechRepublic's Geek Trivia.</em></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:85a5cfe91af449478d329e7600d1c0ef">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/YeahTrivia-Creating-a-Trivia-ServerClient-with-WPF-and-WCF</comments>
      <itunes:summary>




In this article I&#39;ll take you along for the ride as I attack the learning curve required to create a fun, interactive application using both the Microsoft Windows Presentation Foundation (WPF) and the Windows Communication
 Foundation (WCF). Afterwards, you&#39;ll have a flexible trivia client/server game ready to play by yourself or against friends, coworkers and your local know-it-all.&amp;nbsp;
And in honor of Halloween, I&#39;ve included three games of horror movie trivia.



Steve Holstad
The Bright Lights

Difficulty: Advanced
Time Required: 
6-10 hours
Cost: Free
Software: Visual Studio Express, 2005, 2008 Beta 2

Microsoft .NET Framework 3.0
Hardware: 
Download: Download Source








&amp;nbsp; 
What can YeahTrivia do for me?
Glad you asked. This project started when I decided I wanted to dive headfirst into learning WPF and WCF, without hacking through countless Hello World examples.&amp;nbsp; And I wanted something fun that I could improve over time as my skills developed in these new
 technologies.&amp;nbsp; In this article I&#39;ll take you along for the ride as I attack the learning curve required to create a fun, interactive application using both the Microsoft Windows Presentation Foundation (WPF) and the Windows Communication Foundation (WCF).
 Afterwards, you&#39;ll have a flexible trivia client/server game ready to play by yourself or against friends, coworkers and your local know-it-all.&amp;nbsp; And in honor of Halloween, I&#39;ve included three games of horror movie trivia. 

 
In case you were wondering, the &amp;quot;YeahTrivia&amp;quot; name honors my new bride&amp;nbsp;&amp;amp; her&amp;nbsp;favorite prefix.&amp;nbsp; Think of it as&amp;nbsp;YeeeeaaaaahhTrivia! 
Basic Setup
This demo project was built using Visual Studio 2008 Beta 2, and is based on the Microsoft .NET Framework version 3.0.&amp;nbsp; The game is fed by a small windows app that acts as a game server, providing game selection, user&amp;nbsp;registration, question loading, response
 times, chat messaging&amp;nbsp;and scorekeeping.&amp;nbsp; The server </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/YeahTrivia-Creating-a-Trivia-ServerClient-with-WPF-and-WCF</link>
      <pubDate>Mon, 29 Oct 2007 21:01:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/YeahTrivia-Creating-a-Trivia-ServerClient-with-WPF-and-WCF</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/5773166_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/5773166_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Steve Holstad</dc:creator>
      <itunes:author>Steve Holstad</itunes:author>
      <slash:comments>12</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/YeahTrivia-Creating-a-Trivia-ServerClient-with-WPF-and-WCF/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Halloween</category>
      <category>Windows</category>
      <category>arcade</category>
      <category>windows miscellaneous</category>
      <category>card and board games</category>
    </item>
  <item>
      <title>Silverlight 8-Ball</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50"><img height="48" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/8BallSmall.png" width="48"></td>
<td><span class="entry_description">In this article, I will discuss how I have built a 2 player 8-Ball game in Silverlight (<a href="http://employees.claritycon.com/jpetersen/Silverlight8Ball/">play here</a>). I will explain how I used the Expression tools
 to design the graphics and various .NET techniques to enable user control and game animation.
</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Justin Petersen</div>
<div class="entry_company"><a href="http://www.claritycon.com/coding4fun">Coding4Fun at Clarity</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
6-10 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn2.microsoft.com/en-us/vstudio/">Visual Studio 2008 Beta 2</a>,
<a href="http://msdn2.microsoft.com/en-us/silverlight/">Silverlight 1.1 Alpha Refresh</a>,
<a href="http://www.microsoft.com/expression/products/overview.aspx?key=design">Expression Design</a>,
<a href="http://www.microsoft.com/expression/products/features.aspx?key=blend2preview">
Expression Blend 2 Preview</a> </span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/342985_Silverlight8Ball.zip">Download</a>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p></p>
<p>In this article, I will discuss how I have built a 2 player 8-Ball game in Silverlight (<a href="http://employees.claritycon.com/jpetersen/Silverlight8Ball/">play here</a>). I will explain how I used the Expression tools to design the graphics and various
 .NET techniques to enable user control and game animation.&nbsp; </p>
<p>The following components must be implemented to complete this game: </p>
<ol>
<li>Graphics (pool table, pool ball, and pool stick) </li><li>Vector animation and collision physics </li><li>User interaction&nbsp; </li><li>Game state and control</li></ol>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/Silverlight8Ball18.png"><img height="335" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/Silverlight8Ball_thumb12.png" width="439" border="0"></a>
</p>
<p>Before I continue, I'd like to point out that I did not originate all of the code and XAML for this solution. I came up with the idea of creating a Silverlight 8-Ball game after stumbling upon a 2-D “bouncing bubble” animation here:
<a href="http://www.bubblemark.com/">http://www.bubblemark.com/</a>&nbsp;created by Alexey Gavrilov.&nbsp;
</p>
<p>The original intent for this solution was to compare the performance of the bouncing bubbles across&nbsp;various platforms.&nbsp; I found this very useful, but was personally interested in making something fun and interactive out of it.&nbsp;
</p>
<h1></h1>
<h2><b>Getting Started</b></h2>
<h5><strong>Prerequisites </strong></h5>
<p>The following tools were used to implement this solution: </p>
<ul>
<li>Visual Studio 2008 Beta 2 </li><li>Silverlight 1.1 Alpha Refresh&nbsp; </li><li>Expression Design </li><li>Expression Blend</li></ul>
<h5><strong>Learning more about game development</strong> </h5>
<p>If you'd like to learn more about game development, I found a number Coding4Fun posts&nbsp;under Gaming helpful.&nbsp; In particular,&nbsp;the&nbsp;<a href="http://blogs.msdn.com/coding4fun/archive/2007/02/20/1727608.aspx">2D Game Primer</a>&nbsp;by &quot;ZMan&quot; gives a good overview
 of the basics (e.g. GameLoop, Sprites, etc.)</p>
<h2><b>Graphics</b> </h2>
<p>I am not much of a&nbsp;graphic&nbsp;designer.&nbsp; In fact, I've spent the majority of my career designing and implementing line of business apps for enterprise customers (typically not a very graphically intensive task).&nbsp; So I believe it is a decent testament to the&nbsp;effectiveness
 of the Microsoft Expression suite that I could, in short order, create the graphics for this game.&nbsp;
</p>
<p>I used Expression Design to build the graphics of the pool table.&nbsp; Modeling my design&nbsp;after the standard dimension of a 9 foot billiards table,&nbsp;I drew the main structure&nbsp;as a rectangle with rounded corners.&nbsp;&nbsp;I drew a smaller green rectangle centered over
 it for the playing surface (of course following standard dimensions).&nbsp; Next, I created 6 black circles placed one level behind the playing surface to give the impression of pockets.&nbsp; Lastly, I added the wood texture to the outside rectangle (which was super
 easy as there is a set of wood textures available by default), and drew a simple rounded rectangle beneath the table to serve as a status bar.&nbsp;
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image03.png"><img height="272" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image0_thumb1.png" width="437" border="0"></a>
</p>
<p>I also created the graphics for my pool stick using Expression Design.&nbsp; This consisted of a few tapered polygons and 2 half circles for the butt and tip.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image011.png"><img height="229" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image0_thumb5.png" width="433" border="0"></a>
</p>
<p>After exporting the associated XAML, I imported each element into my project.&nbsp; From here, I could view and refine the design through a scaled down visual editor or the associated XAML.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image021.png"><img height="271" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image0_thumb9.png" width="433" border="0"></a>
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image024.png"><img height="270" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image0_thumb10.png" width="433" border="0"></a>
</p>
<p>Lastly, I inspected the&nbsp;XAML markup for the pool ball I reused from Alexey's Bubblemark solution.&nbsp; I needed to understand the properties of this object so that I could modify the color of the balls later on.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image018.png"><img height="272" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5002772/image0_thumb8.png" width="436" border="0"></a>
</p>
<h2><b>Vector Animation and Collision Physics</b> </h2>
<p>The root of Silverlight8Ball is a Storyboard (x:Name=”GameLoop”) that acts as a triggering mechanism for determining ball velocity, direction, and redirection due to collision. Whereas some Storyboards are implemented with predetermined paths and timelines
 directly in XAML, the action taken at each tick must be determined dynamically in this game. So we simply set the duration to 00:00:0, and handle the Completed event to trigger our positioning logic. This design effectively creates what game developers call
 a “Game Loop” that triggers continuous processing to determine application state.
</p>
<p>The resulting “GameLoop_Completedhandler” becomes the root processing agent for all of the game's ball movement logic.&nbsp;&nbsp;
</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>void</span> GameLoop_Completed(<span>object</span> sender, EventArgs e)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     <span>switch</span> (m_ActionState)</pre>
<pre><span>   4:</span>     {</pre>
<pre><span>   5:</span>         <span>case</span> m_ActionStates.BallsMoving:</pre>
<pre><span>   6:</span> &nbsp;</pre>
<pre><span>   7:</span>             <span>// prep</span></pre>
<pre><span>   8:</span>             List&lt;Ball&gt; removeList = <span>new</span> List&lt;Ball&gt;();</pre>
<pre><span>   9:</span>             <span>bool</span> someBallsAreMoving = <span>false</span>;</pre>
<pre><span>  10:</span> &nbsp;</pre>
<pre><span>  11:</span>             <span>// move each ball</span></pre>
<pre><span>  12:</span>             <span>foreach</span> (Ball ball <span>in</span> m_GameBalls)</pre>
<pre><span>  13:</span>             {</pre>
<pre><span>  14:</span>                 ball.Move();</pre>
<pre><span>  15:</span>                 <span>if</span> (ball.InPocket) removeList.Add(ball);</pre>
<pre><span>  16:</span>                 <span>else</span> <span>if</span> (ball.IsMoving) someBallsAreMoving = <span>true</span>;</pre>
<pre><span>  17:</span>             }</pre>
<pre><span>  18:</span> &nbsp;</pre>
<pre><span>  19:</span>             <span>// store balls sunk on shot and update ui </span></pre>
<pre><span>  20:</span>             <span>foreach</span> (Ball ball <span>in</span> removeList)</pre>
<pre><span>  21:</span>             {</pre>
<pre><span>  22:</span>                 sunkBalls.Add(ball);</pre>
<pre><span>  23:</span>                 RemoveBall(ball);</pre>
<pre><span>  24:</span>             }</pre>
<pre><span>  25:</span> &nbsp;</pre>
<pre><span>  26:</span>             <span>if</span> (someBallsAreMoving)</pre>
<pre><span>  27:</span>             {</pre>
<pre><span>  28:</span>                 <span>// update vectors for ball collisions</span></pre>
<pre><span>  29:</span>                 <span>for</span> (<span>int</span> i = 0; i &lt; m_GameBalls.Count; i&#43;&#43;)</pre>
<pre><span>  30:</span>                 {</pre>
<pre><span>  31:</span>                     <span>for</span> (<span>int</span> j = i &#43; 1; j &lt; m_GameBalls.Count; j&#43;&#43;)</pre>
<pre><span>  32:</span>                     {</pre>
<pre><span>  33:</span>                         m_GameBalls[i].DoCollide(m_GameBalls[j]);</pre>
<pre><span>  34:</span>                     }</pre>
<pre><span>  35:</span>                 }</pre>
<pre><span>  36:</span>             }</pre>
<pre><span>  37:</span>             <span>else</span></pre>
<pre><span>  38:</span>             {</pre>
<pre><span>  39:</span>                 <span>// determine shot results</span></pre>
<pre><span>  40:</span>                 ShotResults results = EvaluateShot();</pre>
<pre><span>  41:</span> &nbsp;</pre>
<pre><span>  42:</span>                 <span>// apply state and ui changes</span></pre>
<pre><span>  43:</span>                 UpdateGameState(results);</pre>
<pre><span>  44:</span>             }</pre>
<pre><span>  45:</span> &nbsp;</pre>
<pre><span>  46:</span>             <span>break</span>;</pre>
<pre><span>  47:</span>     }</pre>
<pre><span>  48:</span> &nbsp;</pre>
<pre><span>  49:</span>     <span>// restart the storyboard</span></pre>
<pre><span>  50:</span>     <span>if</span> (m_IsRunning)</pre>
<pre><span>  51:</span>     {</pre>
<pre><span>  52:</span>         GameLoop.Begin();</pre>
<pre><span>  53:</span>     }</pre>
<pre><span>  54:</span> &nbsp;</pre>
<pre><span>  55:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Private</span> <span>Sub</span> GameLoop_Completed(<span>ByVal</span> sender <span>As</span> <span>Object</span>, <span>ByVal</span> e <span>As</span> EventArgs)</pre>
<pre><span>   2:</span> &nbsp;</pre>
<pre><span>   3:</span>     <span>Select</span> <span>Case</span> m_ActionState</pre>
<pre><span>   4:</span> &nbsp;</pre>
<pre><span>   5:</span>         <span>Case</span> m_ActionStates.BallsMoving</pre>
<pre><span>   6:</span> &nbsp;</pre>
<pre><span>   7:</span>             <span>' prep</span></pre>
<pre><span>   8:</span>             <span>Dim</span> removeList <span>As</span> List(Of Ball) = <span>New</span> List(Of Ball)()</pre>
<pre><span>   9:</span>             <span>Dim</span> someBallsAreMoving <span>As</span> <span>Boolean</span> = <span>False</span></pre>
<pre><span>  10:</span> &nbsp;</pre>
<pre><span>  11:</span>             <span>' move each ball</span></pre>
<pre><span>  12:</span>             <span>For</span> <span>Each</span> ball <span>As</span> Ball <span>In</span> m_GameBalls</pre>
<pre><span>  13:</span>                 ball.Move()</pre>
<pre><span>  14:</span>                 <span>If</span> ball.InPocket <span>Then</span></pre>
<pre><span>  15:</span>                     removeList.Add(ball)</pre>
<pre><span>  16:</span>                 <span>ElseIf</span> ball.IsMoving <span>Then</span></pre>
<pre><span>  17:</span>                     someBallsAreMoving = <span>True</span></pre>
<pre><span>  18:</span>                 <span>End</span> <span>If</span></pre>
<pre><span>  19:</span>             <span>Next</span> ball</pre>
<pre><span>  20:</span> &nbsp;</pre>
<pre><span>  21:</span>             <span>' store balls sunk on shot and update ui </span></pre>
<pre><span>  22:</span>             <span>For</span> <span>Each</span> ball <span>As</span> Ball <span>In</span> removeList</pre>
<pre><span>  23:</span>                 sunkBalls.Add(ball)</pre>
<pre><span>  24:</span>                 RemoveBall(ball)</pre>
<pre><span>  25:</span>             <span>Next</span> ball</pre>
<pre><span>  26:</span> &nbsp;</pre>
<pre><span>  27:</span>             <span>If</span> someBallsAreMoving <span>Then</span></pre>
<pre><span>  28:</span>                 <span>' update vectors for ball collisions</span></pre>
<pre><span>  29:</span>                 <span>For</span> i <span>As</span> <span>Integer</span> = 0 <span>To</span> m_GameBalls.Count - 1</pre>
<pre><span>  30:</span>                     <span>For</span> j <span>As</span> <span>Integer</span> = i &#43; 1 <span>To</span> m_GameBalls.Count - 1</pre>
<pre><span>  31:</span>                         m_GameBalls(i).DoCollide(m_GameBalls(j))</pre>
<pre><span>  32:</span>                     <span>Next</span> j</pre>
<pre><span>  33:</span>                 <span>Next</span> i</pre>
<pre><span>  34:</span>             <span>Else</span></pre>
<pre><span>  35:</span>                 <span>' determine shot results</span></pre>
<pre><span>  36:</span>                 <span>Dim</span> results <span>As</span> ShotResults = EvaluateShot()</pre>
<pre><span>  37:</span> &nbsp;</pre>
<pre><span>  38:</span>                 <span>' apply state and ui changes</span></pre>
<pre><span>  39:</span>                 UpdateGameState(results)</pre>
<pre><span>  40:</span>             <span>End</span> <span>If</span></pre>
<pre><span>  41:</span> &nbsp;</pre>
<pre><span>  42:</span>     <span>End</span> <span>Select</span></pre>
<pre><span>  43:</span> &nbsp;</pre>
<pre><span>  44:</span>     <span>' restart the storyboard</span></pre>
<pre><span>  45:</span>     <span>If</span> m_IsRunning <span>Then</span></pre>
<pre><span>  46:</span>         GameLoop.Begin()</pre>
<pre><span>  47:</span>     <span>End</span> <span>If</span></pre>
<pre><span>  48:</span> &nbsp;</pre>
<pre><span>  49:</span> <span>End</span> Sub</pre>
</div>
</div>
<p>The above code snippets demonstrate the full functionality of our GameLoop.&nbsp; However, the primary animation and collision logic are handled by &quot;ball.Move();&quot; and &quot;m_GameBalls[i].DoCollide(m_GameBalls[j]);&quot; lines&nbsp;(in C# example).&nbsp; The Move() function of each
 ball applies its current vector (i.e. x and y &quot;velocities&quot;) to determine its next position and updates the ball's&nbsp;UI element coordinates.&nbsp; Once the ball is advanced, the DoCollide function checks if two balls have collided.&nbsp; If so, their vectors are adjusted
 accordingly.</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>public</span> <span>bool</span> DoCollide(Ball b)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     <span>// calculate some vectors </span></pre>
<pre><span>   4:</span>     <span>double</span> dx = <span>this</span>._x - b._x;</pre>
<pre><span>   5:</span>     <span>double</span> dy = <span>this</span>._y - b._y;</pre>
<pre><span>   6:</span>     <span>double</span> dvx = <span>this</span>._vx - b._vx;</pre>
<pre><span>   7:</span>     <span>double</span> dvy = <span>this</span>._vy - b._vy;</pre>
<pre><span>   8:</span>     <span>double</span> distance2 = dx * dx &#43; dy * dy;</pre>
<pre><span>   9:</span>     </pre>
<pre><span>  10:</span>     <span>if</span> (Math.Abs(dx) &gt; <span>this</span>._d || Math.Abs(dy) &gt; <span>this</span>._d)</pre>
<pre><span>  11:</span>         <span>return</span> <span>false</span>;</pre>
<pre><span>  12:</span>     <span>if</span> (distance2 &gt; <span>this</span>._d2)</pre>
<pre><span>  13:</span>         <span>return</span> <span>false</span>;</pre>
<pre><span>  14:</span> &nbsp;</pre>
<pre><span>  15:</span>     <span>// make absolutely elastic collision</span></pre>
<pre><span>  16:</span>     <span>double</span> mag = dvx * dx &#43; dvy * dy;</pre>
<pre><span>  17:</span> &nbsp;</pre>
<pre><span>  18:</span>     <span>// test that balls move towards each other    </span></pre>
<pre><span>  19:</span>     <span>if</span> (mag &gt; 0)</pre>
<pre><span>  20:</span>         <span>return</span> <span>false</span>;</pre>
<pre><span>  21:</span> &nbsp;</pre>
<pre><span>  22:</span>     mag /= distance2;</pre>
<pre><span>  23:</span> &nbsp;</pre>
<pre><span>  24:</span>     <span>double</span> delta_vx = dx * mag;</pre>
<pre><span>  25:</span>     <span>double</span> delta_vy = dy * mag;</pre>
<pre><span>  26:</span> &nbsp;</pre>
<pre><span>  27:</span>     <span>this</span>._vx -= delta_vx;</pre>
<pre><span>  28:</span>     <span>this</span>._vy -= delta_vy;</pre>
<pre><span>  29:</span> &nbsp;</pre>
<pre><span>  30:</span>     b._vx &#43;= delta_vx;</pre>
<pre><span>  31:</span>     b._vy &#43;= delta_vy;</pre>
<pre><span>  32:</span> &nbsp;</pre>
<pre><span>  33:</span>     <span>return</span> <span>true</span>;</pre>
<pre><span>  34:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Public</span> <span>Function</span> DoCollide(<span>ByVal</span> b <span>As</span> Ball) <span>As</span> <span>Boolean</span></pre>
<pre><span>   2:</span>     <span>' calculate some vectors </span></pre>
<pre><span>   3:</span>     <span>Dim</span> dx <span>As</span> <span>Double</span> = <span>Me</span>._x - b._x</pre>
<pre><span>   4:</span>     <span>Dim</span> dy <span>As</span> <span>Double</span> = <span>Me</span>._y - b._y</pre>
<pre><span>   5:</span>     <span>Dim</span> dvx <span>As</span> <span>Double</span> = <span>Me</span>._vx - b._vx</pre>
<pre><span>   6:</span>     <span>Dim</span> dvy <span>As</span> <span>Double</span> = <span>Me</span>._vy - b._vy</pre>
<pre><span>   7:</span>     <span>Dim</span> distance2 <span>As</span> <span>Double</span> = dx * dx &#43; dy * dy</pre>
<pre><span>   8:</span> &nbsp;</pre>
<pre><span>   9:</span>     <span>If</span> Math.Abs(dx) &gt; <span>Me</span>._d <span>OrElse</span> Math.Abs(dy) &gt; <span>Me</span>._d <span>Then</span></pre>
<pre><span>  10:</span>         <span>Return</span> <span>False</span></pre>
<pre><span>  11:</span>     <span>End</span> <span>If</span></pre>
<pre><span>  12:</span>     <span>If</span> distance2 &gt; <span>Me</span>._d2 <span>Then</span></pre>
<pre><span>  13:</span>         <span>Return</span> <span>False</span></pre>
<pre><span>  14:</span>     <span>End</span> <span>If</span></pre>
<pre><span>  15:</span> &nbsp;</pre>
<pre><span>  16:</span>     <span>' make absolutely elastic collision</span></pre>
<pre><span>  17:</span>     <span>Dim</span> mag <span>As</span> <span>Double</span> = dvx * dx &#43; dvy * dy</pre>
<pre><span>  18:</span> &nbsp;</pre>
<pre><span>  19:</span>     <span>' test that balls move towards each other    </span></pre>
<pre><span>  20:</span>     <span>If</span> mag &gt; 0 <span>Then</span></pre>
<pre><span>  21:</span>         <span>Return</span> <span>False</span></pre>
<pre><span>  22:</span>     <span>End</span> <span>If</span></pre>
<pre><span>  23:</span> &nbsp;</pre>
<pre><span>  24:</span>     mag /= distance2</pre>
<pre><span>  25:</span> &nbsp;</pre>
<pre><span>  26:</span>     <span>Dim</span> delta_vx <span>As</span> <span>Double</span> = dx * mag</pre>
<pre><span>  27:</span>     <span>Dim</span> delta_vy <span>As</span> <span>Double</span> = dy * mag</pre>
<pre><span>  28:</span> &nbsp;</pre>
<pre><span>  29:</span>     <span>Me</span>._vx -= delta_vx</pre>
<pre><span>  30:</span>     <span>Me</span>._vy -= delta_vy</pre>
<pre><span>  31:</span> &nbsp;</pre>
<pre><span>  32:</span>     b._vx &#43;= delta_vx</pre>
<pre><span>  33:</span>     b._vy &#43;= delta_vy</pre>
<pre><span>  34:</span> &nbsp;</pre>
<pre><span>  35:</span>     <span>Return</span> <span>True</span></pre>
<pre><span>  36:</span> <span>End</span> Function</pre>
</div>
</div>
<h2>User Interaction&nbsp;</h2>
<p>While the GameLoop Storyboard does a good job at managing ball movement, I didn't think it was the&nbsp;best option for handling pool stick&nbsp;and&nbsp;q-ball control.&nbsp; During times of user control (stick aiming and q-ball &quot;ball in hand&quot;), I chose to use mouse movement
 and&nbsp;click events to determine object position and angle.&nbsp; I created my own enumeration to manage switching between ball movement and user control&nbsp;states.&nbsp; The rest involves some simple statistics and Silverlight XAML transformations.
</p>
<h5><strong>Pool Stick Aiming and Ball-In-Hand</strong></h5>
<p>During a scratch, the MouseMove event allows the affect of moving the q-ball for placement.&nbsp; During aiming, it allows the user to rotate the poolstick around the q-ball.</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>void</span> Page_MouseMove(<span>object</span> sender, MouseEventArgs e)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span> &nbsp;</pre>
<pre><span>   4:</span>     m_MousePoint = e.GetPosition(<span>this</span>);</pre>
<pre><span>   5:</span> &nbsp;</pre>
<pre><span>   6:</span>     <span>switch</span> (m_ActionState)</pre>
<pre><span>   7:</span>     {</pre>
<pre><span>   8:</span>         <span>case</span> m_ActionStates.Scratch:</pre>
<pre><span>   9:</span>             m_QBall.MoveAbsolute(m_MousePoint.X, m_MousePoint.Y);</pre>
<pre><span>  10:</span>             <span>break</span>;</pre>
<pre><span>  11:</span>         <span>case</span> m_ActionStates.Aiming:</pre>
<pre><span>  12:</span>             m_PoolStick.Rotate(m_MousePoint.X, m_MousePoint.Y, m_QBall.BallCenterX, m_QBall.BallCenterY);</pre>
<pre><span>  13:</span>             <span>break</span>;</pre>
<pre><span>  14:</span>     }      </pre>
<pre><span>  15:</span>     </pre>
<pre><span>  16:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Private</span> <span>Sub</span> Page_MouseMove(<span>ByVal</span> sender <span>As</span> <span>Object</span>, <span>ByVal</span> e <span>As</span> MouseEventArgs)</pre>
<pre><span>   2:</span> &nbsp;</pre>
<pre><span>   3:</span>     m_MousePoint = e.GetPosition(<span>Me</span>)</pre>
<pre><span>   4:</span> &nbsp;</pre>
<pre><span>   5:</span>     <span>Select</span> <span>Case</span> m_ActionState</pre>
<pre><span>   6:</span>         <span>Case</span> m_ActionStates.Scratch</pre>
<pre><span>   7:</span>             m_QBall.MoveAbsolute(m_MousePoint.X, m_MousePoint.Y)</pre>
<pre><span>   8:</span>         <span>Case</span> m_ActionStates.Aiming</pre>
<pre><span>   9:</span>             m_PoolStick.Rotate(m_MousePoint.X, m_MousePoint.Y, m_QBall.BallCenterX, m_QBall.BallCenterY)</pre>
<pre><span>  10:</span>     <span>End</span> <span>Select</span></pre>
<pre><span>  11:</span> &nbsp;</pre>
<pre><span>  12:</span> <span>End</span> Sub</pre>
</div>
</div>
<h5><strong></strong>&nbsp;</h5>
<h5><strong>The RotateTransform Rocks</strong></h5>
<p>The Silverlight RotateTranform is very powerful in this case.&nbsp; It allows me to simply rotate the pool stick object around a center point (the center of the q-ball) using a relative angle between the mouse point and the ball.&nbsp;
</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>public</span> <span>void</span> Rotate (<span>double</span> mouseX, <span>double</span> mouseY, <span>double</span> ballX, <span>double</span> ballY)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     <span>double</span> vx = ballX - mouseX;</pre>
<pre><span>   4:</span>     <span>double</span> vy = ballY - mouseY;</pre>
<pre><span>   5:</span>     </pre>
<pre><span>   6:</span>     radians = Math.Atan2(vy, vx);</pre>
<pre><span>   7:</span>     <span>double</span> angle = radians * (180/Math.PI);</pre>
<pre><span>   8:</span>     </pre>
<pre><span>   9:</span>     rootCanvas.RenderTransform = <span>new</span> RotateTransform </pre>
<pre><span>  10:</span>     { </pre>
<pre><span>  11:</span>         CenterX = Model.stickBuffer, </pre>
<pre><span>  12:</span>         CenterY = Model.stickHeight/2, </pre>
<pre><span>  13:</span>         Angle = angle </pre>
<pre><span>  14:</span>     };</pre>
<pre><span>  15:</span> &nbsp;</pre>
<pre><span>  16:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Public</span> <span>Sub</span> Rotate(<span>ByVal</span> mouseX <span>As</span> <span>Double</span>, <span>ByVal</span> mouseY <span>As</span> <span>Double</span>, <span>ByVal</span> ballX <span>As</span> <span>Double</span>, <span>ByVal</span> ballY <span>As</span> <span>Double</span>)</pre>
<pre><span>   2:</span>     <span>Dim</span> vx <span>As</span> <span>Double</span> = ballX - mouseX</pre>
<pre><span>   3:</span>     <span>Dim</span> vy <span>As</span> <span>Double</span> = ballY - mouseY</pre>
<pre><span>   4:</span> &nbsp;</pre>
<pre><span>   5:</span>     radians = Math.Atan2(vy, vx)</pre>
<pre><span>   6:</span>     <span>Dim</span> angle <span>As</span> <span>Double</span> = radians * (180 / Math.PI)</pre>
<pre><span>   7:</span> &nbsp;</pre>
<pre><span>   8:</span>     <span>Dim</span> transform <span>As</span> RotateTransform = <span>New</span> RotateTransform()</pre>
<pre><span>   9:</span>     transform.CenterX = Model.stickBuffer</pre>
<pre><span>  10:</span>     transform.CenterY = Model.stickHeight / 2</pre>
<pre><span>  11:</span>     transform.Angle = angle</pre>
<pre><span>  12:</span> &nbsp;</pre>
<pre><span>  13:</span>     rootCanvas.RenderTransform = transform</pre>
<pre><span>  14:</span> &nbsp;</pre>
<pre><span>  15:</span> <span>End</span> Sub</pre>
</div>
</div>
<pre><strong></strong>&nbsp;</pre>
<h5><strong>Power Control and Q-Ball Placement</strong></h5>
<p>Based on the ActionState, the mouse up and mouse down events manage user interaction during power adjustment and q-ball placement.</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>void</span> Page_MouseLeftButtonUp(<span>object</span> sender, MouseEventArgs e)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     <span>if</span> (<span>this</span>.m_ActionState == m_ActionStates.AdjustingPower)</pre>
<pre><span>   4:</span>     {</pre>
<pre><span>   5:</span>         m_QBall.Strike(m_PoolStick.power, m_PoolStick.radians);</pre>
<pre><span>   6:</span> &nbsp;</pre>
<pre><span>   7:</span>         m_PoolStick.StopPowerMovement();</pre>
<pre><span>   8:</span>         <span>this</span>.Children.Remove(m_PoolStick);</pre>
<pre><span>   9:</span>         <span>this</span>.m_ActionState = m_ActionStates.BallsMoving;</pre>
<pre><span>  10:</span>     }</pre>
<pre><span>  11:</span> }</pre>
<pre><span>  12:</span> &nbsp;</pre>
<pre><span>  13:</span> <span>void</span> Page_MouseLeftButtonDown(<span>object</span> sender, MouseEventArgs e)</pre>
<pre><span>  14:</span> {</pre>
<pre><span>  15:</span>     <span>switch</span> (m_ActionState)</pre>
<pre><span>  16:</span>     {</pre>
<pre><span>  17:</span>         <span>case</span> m_ActionStates.Aiming:</pre>
<pre><span>  18:</span>             m_PoolStick.StartPowerMovement();</pre>
<pre><span>  19:</span>             <span>this</span>.m_ActionState = m_ActionStates.AdjustingPower;</pre>
<pre><span>  20:</span>             <span>break</span>;</pre>
<pre><span>  21:</span>         <span>case</span> m_ActionStates.Scratch:</pre>
<pre><span>  22:</span>             ResetPoolStick();</pre>
<pre><span>  23:</span>             m_ActionState = m_ActionStates.Aiming;</pre>
<pre><span>  24:</span>             <span>break</span>;</pre>
<pre><span>  25:</span>     }</pre>
<pre><span>  26:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Private</span> <span>Sub</span> Page_MouseLeftButtonUp(<span>ByVal</span> sender <span>As</span> <span>Object</span>, <span>ByVal</span> e <span>As</span> MouseEventArgs)</pre>
<pre><span>   2:</span>     <span>If</span> <span>Me</span>.m_ActionState = m_ActionStates.AdjustingPower <span>Then</span></pre>
<pre><span>   3:</span>         m_QBall.Strike(m_PoolStick.power, m_PoolStick.radians)</pre>
<pre><span>   4:</span> &nbsp;</pre>
<pre><span>   5:</span>         m_PoolStick.StopPowerMovement()</pre>
<pre><span>   6:</span>         <span>Me</span>.Children.Remove(m_PoolStick)</pre>
<pre><span>   7:</span>         <span>Me</span>.m_ActionState = m_ActionStates.BallsMoving</pre>
<pre><span>   8:</span>     <span>End</span> <span>If</span></pre>
<pre><span>   9:</span> <span>End</span> <span>Sub</span></pre>
<pre><span>  10:</span> &nbsp;</pre>
<pre><span>  11:</span> <span>Private</span> <span>Sub</span> Page_MouseLeftButtonDown(<span>ByVal</span> sender <span>As</span> <span>Object</span>, <span>ByVal</span> e <span>As</span> MouseEventArgs)</pre>
<pre><span>  12:</span>     <span>Select</span> <span>Case</span> m_ActionState</pre>
<pre><span>  13:</span>         <span>Case</span> m_ActionStates.Aiming</pre>
<pre><span>  14:</span>             m_PoolStick.StartPowerMovement()</pre>
<pre><span>  15:</span>             <span>Me</span>.m_ActionState = m_ActionStates.AdjustingPower</pre>
<pre><span>  16:</span>         <span>Case</span> m_ActionStates.Scratch</pre>
<pre><span>  17:</span>             ResetPoolStick()</pre>
<pre><span>  18:</span>             m_ActionState = m_ActionStates.Aiming</pre>
<pre><span>  19:</span>     <span>End</span> <span>Select</span></pre>
<pre><span>  20:</span> <span>End</span> Sub</pre>
</div>
</div>
<pre>&nbsp;</pre>
<h2>Game State and Control</h2>
<p>The final component to this application is the &quot;business rules&quot; behind the game.&nbsp; A game of 8-Ball is governed by the results of each player's shot.&nbsp; Whether that shot ends the game or whose shot it is next is based on what balls are sunk.&nbsp;
</p>
<p>I created another enumeration for ShotResults which defines each potential outcome: GoAgain, NextPlayer, Scratch, ScratchOnEight, PrematureEightBall, and Win.&nbsp;
</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>private</span> <span>void</span> UpdateGameState(ShotResults results)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     <span>string</span> resultText = <span>&quot;&quot;</span>;</pre>
<pre><span>   4:</span>     </pre>
<pre><span>   5:</span>     <span>switch</span> (results)</pre>
<pre><span>   6:</span>     {</pre>
<pre><span>   7:</span>         <span>// update game states</span></pre>
<pre><span>   8:</span>         <span>case</span> ShotResults.PrematureEightBall:</pre>
<pre><span>   9:</span>         <span>case</span> ShotResults.ScratchOnEight:</pre>
<pre><span>  10:</span>             resultText = ProcessGameEnd(<span>false</span>, results);</pre>
<pre><span>  11:</span>             m_ActionState = m_ActionStates.GameOver;</pre>
<pre><span>  12:</span>             <span>break</span>;</pre>
<pre><span>  13:</span>         <span>case</span> ShotResults.NextPlayer:</pre>
<pre><span>  14:</span>             resultText = <span>&quot;Player looses turn&quot;</span>;</pre>
<pre><span>  15:</span>             ChangeCurrentPlayer();</pre>
<pre><span>  16:</span>             ResetPoolStick();</pre>
<pre><span>  17:</span>             m_ActionState = m_ActionStates.Aiming;</pre>
<pre><span>  18:</span>             <span>break</span>;</pre>
<pre><span>  19:</span>         <span>case</span> ShotResults.GoAgain:</pre>
<pre><span>  20:</span>             resultText = <span>&quot;Nice job. Go again.&quot;</span>;</pre>
<pre><span>  21:</span>             ResetPoolStick();</pre>
<pre><span>  22:</span>             m_ActionState = m_ActionStates.Aiming;</pre>
<pre><span>  23:</span>             <span>break</span>;</pre>
<pre><span>  24:</span>         <span>case</span> ShotResults.Scratch:</pre>
<pre><span>  25:</span>             resultText = <span>&quot;Scratch. Player looses turn.&quot;</span>;</pre>
<pre><span>  26:</span>             ChangeCurrentPlayer();</pre>
<pre><span>  27:</span>             AddBall(m_QBall);</pre>
<pre><span>  28:</span>             m_ActionState = m_ActionStates.Scratch;</pre>
<pre><span>  29:</span>             <span>break</span>;</pre>
<pre><span>  30:</span>         <span>case</span> ShotResults.Win:</pre>
<pre><span>  31:</span>             resultText = ProcessGameEnd(<span>true</span>, results);</pre>
<pre><span>  32:</span>             m_ActionState = m_ActionStates.GameOver;</pre>
<pre><span>  33:</span>             <span>break</span>;</pre>
<pre><span>  34:</span>     }</pre>
<pre><span>  35:</span> &nbsp;</pre>
<pre><span>  36:</span>     sunkBalls.Clear();</pre>
<pre><span>  37:</span> &nbsp;</pre>
<pre><span>  38:</span>     <span>this</span>.Text_Status.Text = resultText;</pre>
<pre><span>  39:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Private</span> <span>Sub</span> UpdateGameState(<span>ByVal</span> results <span>As</span> ShotResults)</pre>
<pre><span>   2:</span>     <span>Dim</span> resultText <span>As</span> <span>String</span> = <span>&quot;&quot;</span></pre>
<pre><span>   3:</span> &nbsp;</pre>
<pre><span>   4:</span>     <span>Select</span> <span>Case</span> results</pre>
<pre><span>   5:</span>         <span>' update game states</span></pre>
<pre><span>   6:</span>         <span>Case</span> ShotResults.PrematureEightBall, ShotResults.ScratchOnEight</pre>
<pre><span>   7:</span>             resultText = ProcessGameEnd(<span>False</span>, results)</pre>
<pre><span>   8:</span>             m_ActionState = m_ActionStates.GameOver</pre>
<pre><span>   9:</span>         <span>Case</span> ShotResults.NextPlayer</pre>
<pre><span>  10:</span>             resultText = <span>&quot;Player looses turn&quot;</span></pre>
<pre><span>  11:</span>             ChangeCurrentPlayer()</pre>
<pre><span>  12:</span>             ResetPoolStick()</pre>
<pre><span>  13:</span>             m_ActionState = m_ActionStates.Aiming</pre>
<pre><span>  14:</span>         <span>Case</span> ShotResults.GoAgain</pre>
<pre><span>  15:</span>             resultText = <span>&quot;Nice job. Go again.&quot;</span></pre>
<pre><span>  16:</span>             ResetPoolStick()</pre>
<pre><span>  17:</span>             m_ActionState = m_ActionStates.Aiming</pre>
<pre><span>  18:</span>         <span>Case</span> ShotResults.Scratch</pre>
<pre><span>  19:</span>             resultText = <span>&quot;Scratch. Player looses turn.&quot;</span></pre>
<pre><span>  20:</span>             ChangeCurrentPlayer()</pre>
<pre><span>  21:</span>             AddBall(m_QBall)</pre>
<pre><span>  22:</span>             m_ActionState = m_ActionStates.Scratch</pre>
<pre><span>  23:</span>         <span>Case</span> ShotResults.Win</pre>
<pre><span>  24:</span>             resultText = ProcessGameEnd(<span>True</span>, results)</pre>
<pre><span>  25:</span>             m_ActionState = m_ActionStates.GameOver</pre>
<pre><span>  26:</span>     <span>End</span> <span>Select</span></pre>
<pre><span>  27:</span> &nbsp;</pre>
<pre><span>  28:</span>     sunkBalls.Clear()</pre>
<pre><span>  29:</span> &nbsp;</pre>
<pre><span>  30:</span>     <span>Me</span>.Text_Status.Text = resultText</pre>
<pre><span>  31:</span> <span>End</span> Sub</pre>
</div>
</div>
<h2>Conclusion</h2>
<p>This was a fun and educational exercise for me (always a good combination).&nbsp; I learned enough about graphics design to at least fear it less, especially with the use of the Expression suite.&nbsp; It also opened my perspective of Silverlight to understand how
 it will empower us to implement more rich interactive applications.&nbsp; The most interesting part for me, however, was the change in perspective I had to take in implementing an &quot;always on&quot; game.&nbsp; As simple as a game of 8-ball is, it definitely&nbsp;required an&nbsp;adjustment
 in thinking from the event-driven model of programming I'm accustomed to using in my every day work.&nbsp;
</p>
<p>If you have any questions about this solution or have suggestions for improvement, feel free to contact me at
<a href="mailto:jpetersen@claritycon.com">jpetersen@claritycon.com</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:f3798853672545d7ae569e7600d25106">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Silverlight-8-Ball</comments>
      <itunes:summary>




In this article, I will discuss how I have built a 2 player 8-Ball game in Silverlight (play here). I will explain how I used the Expression tools
 to design the graphics and various .NET techniques to enable user control and game animation.




Justin Petersen
Coding4Fun at Clarity

Difficulty: Intermediate
Time Required: 
6-10 hours
Cost: Free
Software: Visual Studio 2008 Beta 2,
Silverlight 1.1 Alpha Refresh,
Expression Design,

Expression Blend 2 Preview 
Hardware: 
Download: Download






 
In this article, I will discuss how I have built a 2 player 8-Ball game in Silverlight (play here). I will explain how I used the Expression tools to design the graphics and various
 .NET techniques to enable user control and game animation.&amp;nbsp;  
The following components must be implemented to complete this game:  

Graphics (pool table, pool ball, and pool stick) Vector animation and collision physics User interaction&amp;nbsp; Game state and control

 
Before I continue, I&#39;d like to point out that I did not originate all of the code and XAML for this solution. I came up with the idea of creating a Silverlight 8-Ball game after stumbling upon a 2-D “bouncing bubble” animation here:
http://www.bubblemark.com/&amp;nbsp;created by Alexey Gavrilov.&amp;nbsp;
 
The original intent for this solution was to compare the performance of the bouncing bubbles across&amp;nbsp;various platforms.&amp;nbsp; I found this very useful, but was personally interested in making something fun and interactive out of it.&amp;nbsp;
 

Getting Started
Prerequisites 
The following tools were used to implement this solution:  

Visual Studio 2008 Beta 2 Silverlight 1.1 Alpha Refresh&amp;nbsp; Expression Design Expression Blend
Learning more about game development 
If you&#39;d like to learn more about game development, I found a number Coding4Fun posts&amp;nbsp;under Gaming helpful.&amp;nbsp; In particular,&amp;nbsp;the&amp;nbsp;2D Game Primer&amp;nbsp;by &amp;quot;ZMan&amp;quot; gives a good overview
 of the basics (e.g. GameLoop, Sprites, etc.) 
Grap</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Silverlight-8-Ball</link>
      <pubDate>Wed, 19 Sep 2007 21:03:50 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Silverlight-8-Ball</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/5002772_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/5002772_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Justin Petersen</dc:creator>
      <itunes:author>Justin Petersen</itunes:author>
      <slash:comments>20</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Silverlight-8-Ball/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Web</category>
      <category>arcade</category>
      <category>web miscellaneous</category>
    </item>
  <item>
      <title>WPF Dartboard scoring application</title>
      <description><![CDATA[<span id="c4fmetadata">
<table border="0" cellspacing="0" cellpadding="1" width="100%">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">In this article I'll review the steps to creating a WPF-based touch-screen scoreboard application that we use in our Clarity Cricket recreational dart league. In doing so, I'll show some examples of how to create custom animations
 in Visual Studio .NET and wire them up to StoryBoards in XAML </span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Jerry Brunning</div>
<div class="entry_company"><a href="http://www.claritycon.com/">Clarity Consulting, Inc.</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Advanced</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
Greater than 10 hours (to build custom animations)</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input">Microsoft Visual Studio 2005 .NET Framework, 3.0 November 2006 CTP of the Visual Studio 2005 extensions for .NET Framework 3.0, Microsoft Expression Blend 2 May Preview</span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/WPFDartboard.zip">Source code</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>In this article I'll review the steps to creating a WPF-based touch-screen scoreboard application that we use in our Clarity Cricket recreational dart league.&nbsp; In doing so, I'll show some examples of how to create custom animations&nbsp;in Visual Studio .Net
 and wire them up to StoryBoards in XAML
<p>Back in October one of my co-workers at Clarity, Kevin Marshall, wrote an article about how he modified the foosball table in our employee lounge to allow us to track game results and individual player statistics (see article
<a href="http://blogs.msdn.com/coding4fun/archive/2006/10/31/910302.aspx">here</a>). Statistics are the basis for bragging rights, and at a competitive software development company, we're big on bragging rights. Following in the tradition of the foosball, we
 next set out to make similar capabilities to track scoring and statistics for our recreational dart board. We ended up building a WPF-enabled windows form-based application to use as our virtual scoreboard, attached it to a touch screen monitor, and hooked
 it up to a database to track statistics. This article will show how we went about building a Cricket scoreboard application.&nbsp;
</p>
<p>Since the application makes heavy use of animations, a video works better to convey some of the features.&nbsp; You can view a video of the dart board application in action
<a href="http://employees.claritycon.com/jbrunning/coding4fun/dartboard.wmv">here</a>.</p>
<h3>Windows Presentation Foundation</h3>
<p>Windows Presentation Foundation (WPF) is Microsoft's next generation framework for building rich user experiences for both forms-based and web-based applications. At the core of WPF is the Extensible Application Markup Language (XAML – pronounced “Zamel”)
 which allows developers to lay out a user interface using XML in a hierarchical tree structure. If you're not familiar with WPF, you may want to stop reading this article and first read an overview of WPF on
<a href="http://msdn2.microsoft.com/en-us/library/ms754130.aspx">MSDN</a>. This article assumes you have a basic understanding of the concepts of WPF. I built the application in this article using the November 2006 CTP of the Visual Studio 2005 extensions for
 .NET Framework 3.0. Make sure you install the .NET 3.0 runtime prior to installing the Visual Studio extensions.</p>
<h3>Laying out the main form</h3>
<p>In support of WPF, Microsoft has released a slew of tools that make writing WPF applications easier. Expression Studio is a suite of tools that Microsoft market's towards “creative designers”, but these tools are equally important for developers, especially
 with the WPF framework's designer glitches in the current release. In many cases you cannot use the designers built into Visual Studio. For example, if your forms use controls that you create, you will not be able to open your XAML file in the visual designer
 in Visual Studio. To get around this, you can use Expression Blend to open your Visual Studio project and view your form (Expression Blend can natively open Visual Studio project and solution files).</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/Scoreboard_Expression2.jpg"><img border="0" alt="Scoreboard_Expression2" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/Scoreboard_Expression2_thumb.jpg" width="500" height="300"></a>
</p>
<p><strong>Figure 1: Microsoft Expression Blend XAML editor</strong></p>
<p>Expression Blend is great for editing XAML and creating Storyboard (animations) but it is important to note that the tool is not a code editor.&nbsp; You cannot edit the .NET code behind files or even HTML or Javascript files from within Expression Blend.&nbsp; However,
 there is nice integration with Visual Studio .NET - opening a code file from within Expression Blend will automatically kick off an instance of Visual Studio, open your solution, and present you with the source file to edit.</p>
<p>Our application contains just a few screens - the main dartboard form, plus a couple forms used to manage the players in the game and view statistics. Our scoreboard application will be run in a kiosk and use a touch screen monitor as the main interface.
 The idea is that a player throws the dart, and then touches the appropriate section of the screen to indicate where the dart landed. The scoreboard then tracks the score and statistics based on the accumulated data.<br>
To create the main form I started with a vector image of a dartboard and used Expression Design to export the image to XAML. The vector image consists of paths for each individual component so the resulting XAML will contain the details for each path. Below
 is a sample snippet from a one of the Path elements in the scoreboard's XAML. Each individual Path element makes up a second of the image.
</p>
<blockquote>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Path</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Path&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;93.8075&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;113.784&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;120.154&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;641.654&quot;</span> <span class="attr">Stretch</span><span class="kwrd">=&quot;Fill&quot;</span> <span class="attr">Fill</span><span class="kwrd">=&quot;#FFFF1A00&quot;</span> <span class="attr">Data</span>=&quot;<span class="attr">F1</span> <span class="attr">M</span>... <span class="kwrd">/&gt;</span></pre>
</blockquote>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Once I have the XAML representation of the board, I can rename the individual Path elements and make them “clickable” by simply adding the appropriate attributes to each Path element, and then writing the event handler in the code behind file. In this case,
 I added the OnLeftMouseUp attribute to each Path element which would be raised for each section whenever the player clicks on the board.</p>
<blockquote>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Path</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Double16&quot;</span> <span class="attr">MouseLeftButtonUp</span><span class="kwrd">=&quot;Double16Click&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;93.8075&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;113.784&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;120.154&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;641.654&quot;</span> <span class="attr">Stretch</span><span class="kwrd">=&quot;Fill&quot;</span> <span class="attr">Fill</span><span class="kwrd">=&quot;#FFFF1A00&quot;</span> <span class="attr">Data</span>=&quot;<span class="attr">F1</span> <span class="attr">M</span>... <span class="kwrd">/&gt;</span></pre>
</blockquote>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In the example Path above – the Double16 – the resulting code behind that would handle the event looks like this:</p>
<blockquote>
<pre class="csharpcode">C#</pre>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">void</span> Double16Click(<span class="kwrd">object</span> sender, EventArgs e)
        {
            OnDartThrown(Darts.Dart16, 2);
        }</pre>
<blockquote>
<pre class="csharpcode">VB</pre>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">Private</span> <span class="kwrd">Sub</span> Double16Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> MouseButtonEventArgs)
            OnDartThrown(Data.Darts.Dart16, 2)
        <span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The OnDartThrown method simply performs a swtich on the Dart enum and performs the appropriate animation followed by notifying the game class to record the score.
<br>
</p>
<h3>Scoring and Rules</h3>
<p>Since we envision using this framework to support multiple dart games, we created a BaseGame class and derived a CricketGame class from BaseGame. Our scoreboard has a member variable of type BaseGame that is set to an instance of the current game type (note:
 we didn't implement multiple game types yet –that could be done by adding an additional screen to choose the type of game to play – so for this version all games are of type Cricket). Our BaseGame has a virtual method called UpdateGame that is called after
 every dart is thrown. This gives the game class a change to update any game data, player scores, statitistics, or other state as required. Since our game is Cricket, CricketGame class manages the scoring rules specific to Cricket, such as maintaining open/close
 state of each target number: </p>
<blockquote>
<p>C#</p>
</blockquote>
<blockquote>
<pre class="csharpcode"><span class="kwrd">   if</span> (lastDartThrown != Darts.DartOutOfBounds)
   {
       score = UpdateScores(lastDartThrown, numberThrown);
       UpdateClosedStatus(lastDartThrown);
   }

   List&lt;<span class="kwrd">int</span>&gt; dartMarks = _players[_currentPlayerIndex].MarkDart(lastDartThrown, numberThrown);
   _dartHistory.Push(<span class="kwrd">new</span> DartHistoryItem(score, lastDartThrown, numberThrown,wasClosed, _currentPlayerIndex, _round, dartMarks));</pre>
</blockquote>
<blockquote>
<pre class="csharpcode">VB</pre>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">If</span> lastDartThrown &lt;&gt; Darts.DartOutOfBounds <span class="kwrd">Then</span>
            score = UpdateScores(lastDartThrown, numberThrown)
            UpdateClosedStatus(lastDartThrown)
        <span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<pre class="csharpcode">        <span class="kwrd">Dim</span> dartMarks <span class="kwrd">As</span> List(Of <span class="kwrd">Integer</span>) = _players(_currentPlayerIndex).MarkDart(lastDartThrown, numberThrown)
        _dartHistory.Push(<span class="kwrd">New</span> DartHistoryItem(score, lastDartThrown, numberThrown, _
        wasClosed, _currentPlayerIndex, _round, dartMarks))</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h3>Setting up the animations</h3>
<p>One of the key new capabilities WPF gives to developers is a way to add animations to their applications. For the dartboard framework, we wanted to add animations after each scoring throw. To give us a good variety, we played around with several different
 types of animations as part of the storyboards in our application.&nbsp; For the dartboard scoreboard we built custom animations for various events that occur during the game – scoring throws, transitions between the scoreboard and the settings screens, and transitions
 between rounds during the game. We implemented our animations in .Net and referenced the .Net classes from within the XAML by adding a namespace declaration in the root node of our scoreboard XAML file. Referencing .Net code from within XAML (and also referencing
 XAML-defined elements from within .Net) is an important concept to understand when writing complex WPF applications.</p>
<blockquote>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">UserControl</span>
    <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span class="attr">xmlns:uc</span><span class="kwrd">=&quot;clr-namespace:DartScoreboard.GUI.Controls&quot;</span> 
    <span class="attr">xmlns:CustomAnimations</span><span class="kwrd">=&quot;clr-namespace:DartScoreboard.Animations&quot;</span> ...<span class="kwrd">/&gt;</span>
</pre>
</blockquote>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>With the namespace for our custom animations declared, we can reference them via storyboards in the XAML. For example, the XAML below is a storyboard that refers to our BounceDoubleAnimation.
</p>
<pre class="csharpcode">      <span class="kwrd">&lt;</span><span class="html">Storyboard</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;roundChangedAnimation&quot;</span> <span class="attr">SpeedRatio</span><span class="kwrd">=&quot;2.0&quot;</span><span class="kwrd">&gt;</span>               
              <span class="kwrd">&lt;</span><span class="html">CustomAnimations:BounceDoubleAnimation</span>
                    <span class="attr">From</span><span class="kwrd">=&quot;-500&quot;</span> <span class="attr">To</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">Duration</span><span class="kwrd">=&quot;0:0:5&quot;</span> <span class="attr">EdgeBehavior</span><span class="kwrd">=&quot;EaseOut&quot;</span> 
            <span class="attr">Storyboard</span>.<span class="attr">TargetName</span><span class="kwrd">=&quot;roundChangedBounce&quot;</span> 
            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;(TranslateTransform.Y)&quot;</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">StoryBoard</span><span class="kwrd">&gt;</span></pre>
<pre class="csharpcode"><span class="kwrd"></span>&nbsp;</pre>
<p>This animation is used during the transition from one round to the next, and results in the text bouncing as it moves from the top of the screen to the bottom.
</p>
<h4>DependencyProperties</h4>
<p>One of the steps in implementing the animation in a .Net code-behind class is to define DependencyProperties. DependencyProperties are special types of properties that can be used by WPF to perform things like data binding, animations, inheritance, and styling.
 It is DependencyProperties, for example, that allow the WPF runtime to render the styling of a child element based on where it is nested in the XAML tree.&nbsp; For our custom animations, any properties we want to add to our classes that affect or control the animation
 behavior must be defined as DependencyProperties.&nbsp; For example, our BounceDoubleAnimation has a property called EdgeBehavior that controls whether the animation starts on the screen and moves off the screen (EdgeOut) or starts off the screen and moves onto
 the screen (EdgeIn).&nbsp; We define this as a DependencyProperty below.</p>
<p>Creating a DependencyProperty in your code required two steps: First, you need to register the property with WPF. Second, you need to define property Get and Set methods that call the special GetValue and SetValue functions used to read and write DependencyProperties.
 The example below shows how to register the “EdgeBehavior” DependencyProperty used by the BounceDoubleAnimation:
</p>
<blockquote>
<p>C#</p>
</blockquote>
<p>&nbsp;</p>
<pre class="csharpcode">        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty EdgeBehaviorProperty =
            DependencyProperty.Register(<span class="str">&quot;EdgeBehavior&quot;</span>,
                <span class="kwrd">typeof</span>(EdgeBehaviorEnum),
                <span class="kwrd">typeof</span>(BounceDoubleAnimation),
                <span class="kwrd">new</span> PropertyMetadata(EdgeBehaviorEnum.EaseInOut));</pre>
<blockquote>
<pre class="csharpcode">VB</pre>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">Public</span> <span class="kwrd">Shared</span> EdgeBehaviorProperty <span class="kwrd">As</span> DependencyProperty = _
            DependencyProperty.Register(<span class="str">&quot;EdgeBehavior&quot;</span>, _
                <span class="kwrd">GetType</span>(EdgeBehaviorEnum), _
                <span class="kwrd">GetType</span>(BounceDoubleAnimation), _
                <span class="kwrd">New</span> PropertyMetadata(EdgeBehaviorEnum.EaseInOut))</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This snippet below shows how to create the property Get and Set methods for a DependencyProperty. Notice the calls to the GetValue and SetValue methods.&nbsp;</p>
<blockquote>
<p>C#</p>
</blockquote>
<pre class="csharpcode">        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Specifies which side of the transition gets the &quot;bounce&quot; effect.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> EdgeBehaviorEnum EdgeBehavior
        {
            get
            {
                <span class="kwrd">return</span> (EdgeBehaviorEnum)GetValue(EdgeBehaviorProperty);
            }
            set
            {
                SetValue(EdgeBehaviorProperty, <span class="kwrd">value</span>);
            }
        }</pre>
<blockquote>
<pre class="csharpcode">VB</pre>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">Public</span> <span class="kwrd">Property</span> EdgeBehavior() <span class="kwrd">As</span> EdgeBehaviorEnum
            <span class="kwrd">Get</span>
                <span class="kwrd">Return</span> <span class="kwrd">CType</span>(GetValue(EdgeBehaviorProperty), EdgeBehaviorEnum)
            <span class="kwrd">End</span> <span class="kwrd">Get</span>
            <span class="kwrd">Set</span>(<span class="kwrd">ByVal</span> Value <span class="kwrd">As</span> EdgeBehaviorEnum)
                SetValue(EdgeBehaviorProperty, Value)
            <span class="kwrd">End</span> <span class="kwrd">Set</span>
        <span class="kwrd">End</span> Property</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Invoking Animations from managed code</h4>
<p>Like most things in WPF, animations can be defined declaratively in the XAML, or via managed code.&nbsp; Similarly, they can be triggered from within the XAML, or dynmaically from .NET.&nbsp; In this case, we've defined the animations in Storyboard elements in the
 XAML, but we'll call them from .NET (for example, as a result of a dart being thrown).&nbsp; It is easy to get a reference to a Storyboard and invoke methods against the managed Storyboard class:&nbsp;</p>
<blockquote>
<p>C#</p>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">private</span> <span class="kwrd">void</span> AnimateDoubleBull()
        {
            Storyboard doubleBullAnimation = (Storyboard)FindResource(<span class="str">&quot;doubleBullAnimation&quot;</span>);
            doubleBullAnimation.Begin(<span class="kwrd">this</span>);
        }</pre>
<blockquote>
<pre class="csharpcode">VB</pre>
</blockquote>
<pre class="csharpcode">        <span class="kwrd">Private</span> <span class="kwrd">Sub</span> AnimateDoubleBull()
            <span class="kwrd">Dim</span> doubleBullAnimation <span class="kwrd">As</span> Storyboard = <span class="kwrd">CType</span>(FindResource(<span class="str">&quot;doubleBullAnimation&quot;</span>), Storyboard)
            doubleBullAnimation.Begin(<span class="kwrd">Me</span>)
        <span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h3>Putting it all together</h3>
<p>While all the WPF related features were fun to build, the real purpose of the framework is to track statistics. For our purposes we will track the typical win/loss record, plus player efficiency, which is the ratio of darts thrown to scoring throws. Since
 a “scoring throw” has a different meaning depending on what game is being played, we write the code to handle scoring in the derived BaseCricket class. For example, for Cricket we define a scoring throw as any throw that hits a 15 or higher, or a bullseye.
 We store this per player in a simple database and then compile statistics on the most efficient players. This isn't perfect of course but it works well for what we wanted. With a little work (and some interruption to the game's flow), you could compile statistics
 on a per target level to answer questions like who is the best at hitting the triple 20.
</p>
<p>With the game framework coded and looking good we next looked to find a good place to position the touch screen monitor. We wanted a place that was convenient to the thrower, but yet not in the way. At first we mounted the monitor on the wall adjacent to
 the thrower. This worked well but we didn't have a good place to put the PC. We eventually ended up building a kiosk to house the PC with an angled top containing the touch screen monitor.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/P6190002.jpg"><img border="0" alt="P6190002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/P6190002_thumb.jpg" width="360" height="480"></a>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/P6190004.jpg">
<img border="0" alt="P6190004" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/3425360/P6190004_thumb.jpg" width="360" height="480"></a>
</p>
<p>This made the whole presentation seem a little nicer and with the addition of some color and a couple Clarity logos it could make a great conversation piece when it comes to recruiting.</p>
<pre></pre>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c1f09b20b8724fc18ab69e7600d38ddd">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/WPF-Dartboard-scoring-application</comments>
      <itunes:summary>



&amp;nbsp;
In this article I&#39;ll review the steps to creating a WPF-based touch-screen scoreboard application that we use in our Clarity Cricket recreational dart league. In doing so, I&#39;ll show some examples of how to create custom animations
 in Visual Studio .NET and wire them up to StoryBoards in XAML 



Jerry Brunning
Clarity Consulting, Inc.

Difficulty: Advanced
Time Required: 
Greater than 10 hours (to build custom animations)
Cost: Free
Software: Microsoft Visual Studio 2005 .NET Framework, 3.0 November 2006 CTP of the Visual Studio 2005 extensions for .NET Framework 3.0, Microsoft Expression Blend 2 May Preview
Download: Source code







In this article I&#39;ll review the steps to creating a WPF-based touch-screen scoreboard application that we use in our Clarity Cricket recreational dart league.&amp;nbsp; In doing so, I&#39;ll show some examples of how to create custom animations&amp;nbsp;in Visual Studio .Net
 and wire them up to StoryBoards in XAML
Back in October one of my co-workers at Clarity, Kevin Marshall, wrote an article about how he modified the foosball table in our employee lounge to allow us to track game results and individual player statistics (see article
here). Statistics are the basis for bragging rights, and at a competitive software development company, we&#39;re big on bragging rights. Following in the tradition of the foosball, we
 next set out to make similar capabilities to track scoring and statistics for our recreational dart board. We ended up building a WPF-enabled windows form-based application to use as our virtual scoreboard, attached it to a touch screen monitor, and hooked
 it up to a database to track statistics. This article will show how we went about building a Cricket scoreboard application.&amp;nbsp;
 
Since the application makes heavy use of animations, a video works better to convey some of the features.&amp;nbsp; You can view a video of the dart board application in action
here. 
Windows Presentation Foundation
Windows Presentation Founda</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/WPF-Dartboard-scoring-application</link>
      <pubDate>Wed, 20 Jun 2007 11:34:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/WPF-Dartboard-scoring-application</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/3425360_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/3425360_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Jerry Brunning</dc:creator>
      <itunes:author>Jerry Brunning</itunes:author>
      <slash:comments>13</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/WPF-Dartboard-scoring-application/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Windows</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Tron and Discs of Tron Confirmed for Xbox Live Arcade</title>
      <description><![CDATA[<br>Since the early era of video games, &quot;Tron&quot; has been synonymous as both a landmark CGI film and the engaging arcade games inspired by that film. In honor of the 25th anniversary of &quot;Tron,&quot; Disney Interactive Studios announced the classic arcade games Tron and Discs of Tron will be re-released this summer through Xbox LIVE® <br><br>I swung by the Disney Studios to check out the original and enhanced version first hand. <br class="brclear"><p>&nbsp;</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:70a62c484f4a4d18aa0d9e0f00fd5544">]]></description>
      <comments>http://channel9.msdn.com/Blogs/LauraFoy/Tron-and-Discs-of-Tron-Confirmed-for-Xbox-Live-Arcade</comments>
      <itunes:summary>Since the early era of video games, &amp;quot;Tron&amp;quot; has been synonymous as both a landmark CGI film and the engaging arcade games inspired by that film. In honor of the 25th anniversary of &amp;quot;Tron,&amp;quot; Disney Interactive Studios announced the classic arcade games Tron and Discs of Tron will be re-released this summer through Xbox LIVE&#174; I swung by the Disney Studios to check out the original and enhanced version first hand. &amp;nbsp; </itunes:summary>
      <itunes:duration>380</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/LauraFoy/Tron-and-Discs-of-Tron-Confirmed-for-Xbox-Live-Arcade</link>
      <pubDate>Fri, 08 Jun 2007 14:59:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/LauraFoy/Tron-and-Discs-of-Tron-Confirmed-for-Xbox-Live-Arcade</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/preview/tron_large_on10.jpg" height="240" width="320"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/previewsmall/tron_small_on10.jpg" height="64" width="85"></media:thumbnail>
      <media:group>
        <media:content url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_2MB_on10.wmv" expression="full" duration="380" fileSize="20753681" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_on10.mp3" expression="full" duration="380" fileSize="3032421" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_on10.wma" expression="full" duration="380" fileSize="3072149" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_on10.wmv" expression="full" duration="380" fileSize="23795258" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_s_on10.mp4" expression="full" duration="380" fileSize="24717686" type="video/mp4" medium="video"></media:content>
        <media:content url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_Zune_on10.wmv" expression="full" duration="380" fileSize="30439782" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://on10.net/videos/Tron_on10.asx" expression="full" duration="380" fileSize="102" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://download.microsoft.com/download/7/2/d/72d9d394-e58e-4c48-9129-abe5eace3ef2/Tron_on10.wmv" length="23795258" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Laura Foy</dc:creator>
      <itunes:author>Laura Foy</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/LauraFoy/Tron-and-Discs-of-Tron-Confirmed-for-Xbox-Live-Arcade/RSS</wfw:commentRss>
      <category>Xbox</category>
      <category>Disney</category>
      <category>Video Games</category>
      <category>Tron</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Intro to XNA Part 2: Running Tiny Tennis on the Xbox 360</title>
      <description><![CDATA[
<p>In this article, The ZMan walks through the final steps required to get TinyTennis, a Pong clone, running on your Xbox 360.<br>
The ZMan (Andy Dunn)<br>
<a href="http://www.thezbuffer.com/">TheZBuffer.com</a></p>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free (<a href="http://msdn2.microsoft.com/en-us/xna/bb219592.aspx">Creators Club membership</a> required to deploy to Xbox, additional cost applies)</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/download/">Visual C# Express
</a>, <a href="http://msdn.com/xna/">XNA Game Studio Express</a></span></div>
<div class="entry_details"><strong>Hardware: </strong>Xbox360<span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download:</b> <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=265223">
Starting point C# code</a>, <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=294299">
Final C# code</a></div>
<div class="entry_details">&nbsp;</div>
<p>Welcome to part 2 of the introduction to XNA series.&nbsp;<a href="http://blogs.msdn.com/coding4fun/archive/2006/12/10/1256876.aspx">Last time</a> we converted the TinyTennis sample to use the XNA framework&nbsp;for rendering and keyboard input. However at the time&nbsp;that
 article was written deployment was not available on the Xbox 360. In this article you will make additional changes to the project to enable the game to be deployed and played on your Xbox 360.
</p>
<p>Before you go any further I need to explain how XNA works on the Xbox 360. Microsoft created a version of the .Net compact framework that runs on the Xbox 360, as well as Xbox versions of the XNA assemblies. To get these assemblies onto your Xbox 360 and
 enable deployment of XNA framework requires that you join the <a href="http://msdn2.microsoft.com/en-us/xna/bb219592.aspx">
Creators Club</a>&nbsp;which has a cost associated. The changes you will make for this article will work on the PC too, but you will not be able to play on the Xbox 360 without this. Microsoft have provided a video to help you get this installed:
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=63E75972-4AD0-4CB2-B214-2CA4D7AB9E41">
Getting Started with the XNA Creators Club</a> </p>
<p>Some people have asked why I am using such a simple game for these articles. My reasoning is that I do not want to introduce many new things at the same time. TinyTennis is a very simple game and the GDI version has been on MSDN for a long time now and is
 well documented so I do not need much explanation. Future articles will use more advanced code such as the SpaceWar starter kit.
</p>
<h3></h3>
<h3>Errata for part 1</h3>
<p>Firstly an update to <a href="http://blogs.msdn.com/coding4fun/archive/2006/12/10/1256876.aspx">
part 1</a>. In the rush to get the article out at launch date I converted all the GDI PointF structs into XNA Point structs. This meant that everything was stored as integers rather than floating point values. The rounding is not noticeable in a game this simple,
 but it was incorrect. The correct thing to do was convert to XNA Vector2 structs and this has been corrected in
<a href="http://blogs.msdn.com/coding4fun/archive/2006/12/10/1256876.aspx">the article</a> and the
<a href="http://channel9.msdn.com/ShowPost.aspx?PostID=265223">code for part 1</a>.
</p>
<h3>Making it work with Gamepads</h3>
<p>Those of you with an Xbox 360 will notice that there is no keyboard so controlling the paddles will be a problem. In fact the Xbox 360 does support a standard USB keyboard if you plug one in, its just that very few games look for this input device so there
 is little point in coding for it and certainly no point in mandating it. All Xbox 360 games of course work with the gamepads and TinyTennis will be no exception.
</p>
<p>Xbox 360 gamepads work on the PC as well as on the Xbox. If you have wired controllers you can just plug them in to a vacant USB port and let Windows download the drivers. If you have wireless controllers then you need to buy the wireless controller adapter
 for windows. Note that the charging pack looks like it has a USB connection but that is purely to take electricity to charge the controller - it won't allow you to use the controller on Windows. In addition since the XNA framework only supports the XInput
 API you can <strong>ONLY</strong> use controllers that support this API. In general right now this is Xbox 360 controllers. Any older controllers rely on the DirectInput API which is not available in the XNA framework.
</p>
<p>Reading the gamepad is as simple as reading the keyboard in XNA. You simple get the current state of a particular gamepad using the PlayerIndex enumeration (one, two, three or four corresponding to the players) and then read strongly named properties from
 the gamepad. </p>
<p>Firstly you need to know which player controls each bat so add a PlayerIndex field to bat.cs and modify the constructor to take a PlayerIndex:</p>
<p>&nbsp;</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="kwrd">private</span> PlayerIndex _playerIndex;</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>&nbsp;</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="kwrd">public</span> Bat(<span class="kwrd">int</span> x, Keys up, Keys down, <span class="kwrd">float</span> minPosition, <span class="kwrd">float</span> maxPosition, PlayerIndex playerIndex)
    : <span class="kwrd">base</span>()
{
    initialize(x, minPosition, maxPosition);

    <span class="rem">//Keys to control this sprite </span>
    _upKey = up;
    _downKey = down;

    _playerIndex = playerIndex;
    _isHuman = <span class="kwrd">true</span>;
}
</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>When the bat is created in the constructor of TinyTennis.cs you need to pass in the correct PlayerIndex for each bat (note player 2 is the commented out line)</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="rem">//Create the bat Sprites - they need the keyboard controls and the gameplay area limits</span>
_player1 = <span class="kwrd">new</span> Bat(30, Keys.Q, Keys.A, 0, Window.ClientBounds.Height, PlayerIndex.One);

<span class="rem">//use this line for a second human player</span>
<span class="rem">//_player2 = new Bat(Window.ClientBounds.Width - 30 - Bat.Width, Keys.P, Keys.L, 0, Window.ClientBounds.Height, PlayerIndex.Two);</span>
</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>Finally change the humanMove function in bat.cs to read the gamepad state for the correct gamepad.</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> humanMove()
{
    KeyboardState keyState = Keyboard.GetState();
    GamePadState padState = GamePad.GetState(_playerIndex);

    <span class="kwrd">double</span> velocity = 0.0;
    <span class="rem">//Set the velocity of the sprite based on which keys are pressed</span>
    <span class="kwrd">if</span> (keyState.IsKeyDown(_upKey) || padState.DPad.Up == ButtonState.Pressed)
    {
        velocity &#43;= -_speed;
    }
    <span class="kwrd">if</span> (keyState.IsKeyDown(_downKey) || padState.DPad.Down == ButtonState.Pressed)
    {
        velocity &#43;= _speed;
    }
    Velocity.Y = (<span class="kwrd">int</span>)velocity;
}</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>&nbsp;</p>
<h3>Replacing Windows Sound with XACT</h3>
<p>TinyTennis only has one sound for when the ball bounces. The code currently uses the SoundPlayer class from System.Media. Unfortunately System.Media is one of the assemblies which is not availalbe in the version of the .Net framework on the Xbox 360. The
 only audio API available on the Xbox is called XACT and its exposed in the Microsoft.Xna.Framework.Audio namespace in the XNA framework.</p>
<p>In addition to being the name of the API, XACT also contains a fairly complex sound management tool. In AAA titles the sound guy on the team uses XACT to create a bank of sounds that the programmer can simply play by referring to a 'cue'. The idea behind
 it is to separate the work the audio guy does away from the programmer in the same way as a 3D modeling tool allows an artist to work away from the programmer. If this sounds too complex just to play the bounce sound then you are right - XACT is overkill for
 this. But its the only way to play sounds at the moment, and thankfully you do not need to learn very much XACT to be able to play a WAV file.</p>
<p>Start by running the XACT tool from the start menu. Note that you <strong>MUST</strong> use the version of XACT that ships with XNA Game Studio Express and not one that you may find in a DirectX SDK. The file formats for XACT projects changes almost every
 SDK release and the XNA framework only understands the one it was shipped with. Also note that if you are running on Vista you should
<a href="http://letskilldave.com/archive/2007/02/08/Getting-XNA-Game-Studio-Express-to-run-in-Windows-Vista.aspx">
follow the instructions on Dave's blog</a> to get it to work, and also set it to run as Admin. A future release of XNA Game Studio Express will make everything compatible with Vista.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image01.png"><img height="152" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0.png" width="240" border="0"></a></p>
<p>You will see the XACT window:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image02.png"><img height="480" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb.png" width="572" border="0"></a>
</p>
<p>For TinyTennis you do not need to understand most of this. However there are 2 concepts you need to grasp:</p>
<ol>
<li>Wavebank: This contains the raw sound files </li><li>Soundbank: This contains the 'cues' that you, as the programmer, will play.</li></ol>
<p>In the case of TinyTennis the 'cue' will just play the raw sound file but XACT gives an audio engineer a lot more flexibility than that such as merging multiple sound files, changing the pitch and volume and applying reverb effects.</p>
<p>Create a new wavebank and soundbank by right clicking and selecting New</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image05.png"><img height="98" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb1.png" width="393" border="0"></a>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image09.png">
<img height="77" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb3.png" width="280" border="0"></a>
</p>
<p>You will now see the wavebank and the soundbank windows appear. Add the beep.wav from the project directory by right clicking the wavebank window and selecting Insert Wave Files. In Windows XP you can drag and drop from Windows Explorer into the wavebank
 window.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image012.png"><img height="415" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb4.png" width="407" border="0"></a>
</p>
<p>Then drag the beep from the wave bank window into the top half of the sound bank window (the Sound Name section). Then drag the 'beep' sound into the lower half of the sound bank window (the Cue Name) section. You will end up with something that looks like
 this:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image015.png"><img height="506" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb5.png" width="494" border="0"></a>
</p>
<p>What you have done is created an XACT cue that plays a sound which just contains a single wave file.</p>
<p>Now save the XACT project as TinyTennis.xap in the project folder.</p>
<p>XNA Game Studio Express understands .xap files and will compile&nbsp;correct Windows&nbsp;or Xbox 360 versions when the project is compiled. So the only remaining thing to do is add the .xap to the project. Simple browse and add. Since the .xap file knows which .wav
 files are required you do not need to explicitly reference beep.wav any more so it can be 'excluded from project' (Do not use 'delete' as that will actually remove the file from disc and the .xap file references it).</p>
<p>Playing the sound is a little more complex that the 2 lines of code required with the SoundPlayer class but its much more flexible. For a start you can have more than one sound playing at a time which is not possible with SoundPlayer.</p>
<p>The XACT sound engine needs to be initialized when the game starts up so add the following declarations to TinyTennis.cs (note this was called Game1.cs in part1&nbsp;- I have renamed it for obvious reasons)</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">static</span> AudioEngine engine;
<span class="kwrd">private</span> <span class="kwrd">static</span> WaveBank wavebank;
<span class="kwrd">public</span> <span class="kwrd">static</span> SoundBank soundbank;</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>and then initialize the engine inside the Initialize() function</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Initialize()
{
    engine = <span class="kwrd">new</span> AudioEngine(<span class="str">@&quot;tinytennis.xgs&quot;</span>);
    wavebank = <span class="kwrd">new</span> WaveBank(engine, <span class="str">@&quot;wave bank.xwb&quot;</span>);
    soundbank = <span class="kwrd">new</span> SoundBank(engine, <span class="str">@&quot;sound bank.xsb&quot;</span>);</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>In ball.cs&nbsp;you can remove the&nbsp;using statement for&nbsp;System.Media and add in Microsoft.Xna.Framework.Audio. Then remove all of the places that _beep and SoundPlayer are used.</p>
<p>To play the sound using XACT is a single line replacement inside PlayBounceSound()</p>
<div class="csharpcode-wrapper">
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> playBounceSound()
{
    TinyTennis.soundbank.PlayCue(<span class="str">&quot;beep&quot;</span>);
}</pre>
<style type="text/css">
<!--
.csharpcode-wrapper, .csharpcode-wrapper 
	{background-color:#f4f4f4;
	border:solid 1px gray;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	margin:20px 0px 10px 0px;
	max-height:200px;
	overflow:auto;
	padding:4px 4px 4px 4px;
	width:97.5%}
.csharpcode-wrapper 
	{border-style:none;
	margin:0px 0px 0px 0px;
	overflow:visible;
	padding:0px 0px 0px 0px}
.csharpcode, .csharpcode .csharpcode .alt
	{background-color:#f4f4f4;
	border-style:none;
	color:black;
	font-family:consolas,'Courier New',courier,monospace;
	font-size:8pt;
	line-height:12pt;
	overflow:visible;
	padding:0px 0px 0px 0px;
	width:100%}
.csharpcode 
	{margin:0em}
.csharpcode .alt
	{background-color:white}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .html
	{color:#800000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .lnum
	{color:#606060}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .rem
	{color:#008000}
.csharpcode .str
	{color:#006080}
-->
</style></div>
<p>&nbsp;Compile and run and after all of that hard work you should be back exactly where you started, with the ball playing a beep sound when it bounces.</p>
<h3>Running TinyTennis on the Xbox 360</h3>
<p>Game Studio Express requires you to have separate projects for Windows and Xbox 360 development. For almost all XNA framework projects the source code is identical between the two versions - any slight differences can be handled using #if XBOX - so maintaining
 2 code trees is almost always more trouble than it is worth. The easiest way to get round this is to create both projects in the same directory so that they can share files in a simple manner. You will still have to remember to add a file to both projects
 when you make a new file but that is a simple drag and drop operation. </p>
<p>Firstly create an empty <strong>Xbox 360&nbsp;Game</strong> project somewhere on your hard drive - its a temporary location so anywhere will do. Then using windows explorer copy the .csproj file into the TinyTennisXNA folder and add it to your solution as a second
 project. It will complain about the source files that are missing but that doesn't matter as we will add our own.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image018.png"><img height="211" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb6.png" width="348" border="0"></a>
</p>
<p>Rename the project to TinyTennis360, remove Game1.cs and then drag and drop all the files from TinyTennisXNA into TinyTennis360 - from within the solution explorer. Even though the files are in the same directory they will get added to the new project. Now
 if you modify bat.cs in one project it automatically gets updated in the other project too. The only thing you have to do to keep in sync is remember to drag and drop any new files if you add them to one of the projects.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image024.png"><img height="504" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb8.png" width="246" border="0"></a>
</p>
<p>Now when you compile it will compile both projects. If you only want to compile the windows or the Xbox one you can select it from the platform drop down on the men bar
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image027.png"><img height="116" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1938626/image0_thumb9.png" width="326" border="0"></a>
</p>
<p>Also remember that now you have 2 projects you need to remember to set the right one to be the startup project by right clicking the project file. You will get confused when it tries to run the Xbox project and deploy when you really wanted to debug the
 windows one. </p>
<p>Now that everything compiles its time to deploy it to the Xbox. Rather than explain how to do it in words and pictures I recommend you take a look at the second half of the
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=63E75972-4AD0-4CB2-B214-2CA4D7AB9E41">
Getting Started with the XNA Creators Club</a>&nbsp;video. If you fast forward to 6:02 you can see a demo of how to create the connection between Game Studio Express and your 360 and how to put your Xbox in receive mode. Once that is done you just hit f5 in Game
 Studio Express and the game will be deployed and run. Depending on what screen resolution you have set on your Xbox the paddles may not appear in the expected place, but the game is still playable. To quit the game on the Xbox 360 press the 'back' button on
 gamepad 1. </p>
<p>&nbsp; </p>
<p>Next time I will cover some additional features for the Xbox version and add the scores back in.
</p>
<p>&nbsp; </p>
<p>The ZMan runs the #1 Managed DirectX &amp; XNA&nbsp;community website <a href="http://www.TheZBuffer.com">
http://www.TheZBuffer.com</a>.&nbsp;If you have a question for the ZMan that you would like to se answered in a future column then send it to
<a href="mailto:zman@thezbuffer.com">zman@thezbuffer.com</a>.</p>
<p>Copyright © 2007 ZBuffer Games, LLC</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:aeb5fb29d50f4830b5ce9e7600d4e142">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-2-Running-Tiny-Tennis-on-the-Xbox-360</comments>
      <itunes:summary>
In this article, The ZMan walks through the final steps required to get TinyTennis, a Pong clone, running on your Xbox 360.
The ZMan (Andy Dunn)
TheZBuffer.com 
Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free (Creators Club membership required to deploy to Xbox, additional cost applies)
Software: Visual C# Express
, XNA Game Studio Express
Hardware: Xbox360
Download: 
Starting point C# code, 
Final C# code
&amp;nbsp;
Welcome to part 2 of the introduction to XNA series.&amp;nbsp;Last time we converted the TinyTennis sample to use the XNA framework&amp;nbsp;for rendering and keyboard input. However at the time&amp;nbsp;that
 article was written deployment was not available on the Xbox 360. In this article you will make additional changes to the project to enable the game to be deployed and played on your Xbox 360.
 
Before you go any further I need to explain how XNA works on the Xbox 360. Microsoft created a version of the .Net compact framework that runs on the Xbox 360, as well as Xbox versions of the XNA assemblies. To get these assemblies onto your Xbox 360 and
 enable deployment of XNA framework requires that you join the 
Creators Club&amp;nbsp;which has a cost associated. The changes you will make for this article will work on the PC too, but you will not be able to play on the Xbox 360 without this. Microsoft have provided a video to help you get this installed:

Getting Started with the XNA Creators Club  
Some people have asked why I am using such a simple game for these articles. My reasoning is that I do not want to introduce many new things at the same time. TinyTennis is a very simple game and the GDI version has been on MSDN for a long time now and is
 well documented so I do not need much explanation. Future articles will use more advanced code such as the SpaceWar starter kit.
 

Errata for part 1
Firstly an update to 
part 1. In the rush to get the article out at launch date I converted all the GDI PointF structs into XNA Point structs. This meant that everythin</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-2-Running-Tiny-Tennis-on-the-Xbox-360</link>
      <pubDate>Fri, 23 Mar 2007 15:26:34 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-2-Running-Tiny-Tennis-on-the-Xbox-360</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1938626_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1938626_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Andy Dunn</dc:creator>
      <itunes:author>Andy Dunn</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-2-Running-Tiny-Tennis-on-the-Xbox-360/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Creating .NET AI Bots for Unreal Tournament</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50"><img height="50" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/284239.jpg" width="50"></td>
<td class=""><span class="entry_description">Have you ever played a first person shooter? Then you've probably played against computer controlled players known as &quot;bots&quot; which are computer programs designed with artificial intelligence. Up until now the only
 way to do create your own bot for a game like Unreal Tournament was to learn a bunch of C&#43;&#43; and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express.
</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Andy Sterland (Program Manager, Microsoft),James Lissiak, and Tom Randell
</div>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
Less than 1 hour</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Less Than $50</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a> required, optionally install client and server piece:
<a href="http://www.tucows.com/preview/299071">optional install of Unreal Tournament Game of the Year Edition client</a>,
<a href="http://www.net.dcs.hull.ac.uk/utbot/ServerSetup.aspx">optional Unreal Tournament Server Software</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">None</span></div>
<div class="entry_details"><b>Download: </b><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=284239">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span><br>
<a title="Programming Unreal Tournament AI bots" href="http://soapbox.msn.com/video.aspx?vid=44100721-6a96-4e75-9ea5-acf31aabbd08" target="_new">Video: Programming Unreal Tournament AI bots</a>
<h3>Unreal Tournament &quot;Bots&quot;</h3>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Have you ever played a first person shooter? Then you've probably played against computer controlled players&nbsp;known as &quot;bots&quot; which are computer programs designed with artificial intelligence. Up until now the only way to do create your own bot for a game
 like Unreal Tournament was to learn a bunch of C&#43;&#43; and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express.
</p>
<p>For this project, we created:</p>
<ul>
<li><strong>VB and C# project templates </strong>to simplify setup/installation of the necessary components for Visual Studio Express
</li><li>A&nbsp;<strong>&quot;Bot API mutator</strong>&quot; (custom level) which runs on the server that can accept&nbsp;.NET bots
</li><li>A&nbsp;&quot;<strong>visualizer&quot; </strong>(custom Windows Form app)<strong> </strong>which provides a visual representation of a map so you can watch players play against each other</li></ul>
<p>This project uses the code based on the Mutator for Unreal Tournament at <a href="http://www.planetunreal.com/gamebots/">
http://www.planetunreal.com/gamebots/</a>, but instead&nbsp;creates a .NET wrapper you to code your own &quot;bots&quot; in any .NET language. If you have ever wanted to write software which will take control of a player in Unreal Tournament and duke it out with other killer
 classes, then read on to find out how to do it. </p>
<h3><strong></strong>&nbsp;</h3>
<h3><strong>Getting Started</strong> </h3>
<p><strong>Installing the Game (optional)<br>
</strong>Installing the Game is *not* required as your bots can run on any of the supported
<a href="http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx">remote servers</a>. That being said, if you want to play against your own AI, you can configure your PC to be both a client (with you playing) and a server. You'll find full instructions on server
 configuration below, but to get Unreal Tournament Game of the Year Edition, you can order it from
<a href="http://www.amazon.com/Atari-04-21165-Unreal-Tournament-Game/dp/B00004YC3U">
Amazon.com</a> or download the shareware version ($19.99 for purchase) from <a href="http://www.tucows.com/preview/299071">
Tucows</a>. After installing, make sure to apply the patch up to <a href="http://unreal.epicgames.com/TournamentVersions.htm">
version v436.</a> <br>
</p>
<p><strong>Configuring the Server (optional)<br>
</strong>Your bot can only connect to servers running the “Bot API” mutator meaning you can either run a server locally or join a public server. If you want to run a server, Epic Games distributes the server version of Unreal Tournament for free at: &nbsp;<a href="http://www.fileshack.com/file.x?fid=300">http://www.fileshack.com/file.x?fid=300</a>.
 You&nbsp;can find step-by-step <a href="http://www.net.dcs.hull.ac.uk/utbot/ServerSetup.aspx">
server setup instructions here</a>. If you have a server of your own that is open to all feel free to add it to that list so that other bots from around the world can come round and visit you. Alternatively you can join one of the public servers listed at
<a href="http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx">http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx</a> without the hassle of configuring your own server and the benefit of seeing your AI bot play against other AI bots anywhere in the world.
</p>
<p><strong>Configuring Visual Studio Express<br>
</strong>To simplify configuring Visual Studio Express, we've created project templates for VB and C#. You can download the appropriate:
</p>
<ul>
<li>Visual Basic Project Template </li><li>Visual C# Project Template</li></ul>
<p><a href="http://www.net.dcs.hull.ac.uk/utbot/Files/CS&#43;UT&#43;Remote&#43;Bots.vsi">http://www.net.dcs.hull.ac.uk/utbot/Files/CS&#43;UT&#43;Remote&#43;Bots.vsi</a> (C#)
<a href="http://www.net.dcs.hull.ac.uk/utbot/Files/VB&#43;UT&#43;Remote&#43;Bots.vsi">http://www.net.dcs.hull.ac.uk/utbot/Files/VB&#43;UT&#43;Remote&#43;Bots.vsi</a> (VB)
</p>
<p>Double click on your download to install it and when you next load up Express you should see a “UT Bots” Starter Kit in the new project window.
</p>
<p><strong>Configuring the Visualiser (optional)</strong> <br>
To configure the visualiser, simply run UTBotsVisualiser.exe and enter the IP address for the running game.
</p>
<p><strong></strong>&nbsp;</p>
<h3><strong>Creating Unreal Tournament Bots</strong></h3>
<p><strong>How your Bot works<br>
</strong>You create your bot as a program running on your PC. The PC is connected by the network to the server which needs to be running the “Bot API” mutator. Twice per second the server makes a call to your bot's PerformActions() method, which is a member
 of the RemoteUserBot class. The server will also call methods in your bot when events happen in game, such as your bot hitting a wall or hearing a noise.
</p>
<p><strong>Performing Actions</strong><br>
You put code into the PerformActions method to give your bot its distinctive personality.
</p>
<p>Your aim is to produce a bot that is aware of its own current state and that of the surroundings, reacting in a sensible manner. This may sound complicated, however, thanks to the methods and properties provided in the Getting Started pack, it is incredibly
 simple. </p>
<p><strong>Game Messages</strong><br>
Although the majority of your code will be executed during the call to PerformActions() your bot also receives messages from the server whenever a certain ‘event' occurs.
</p>
<p>For the purpose of clarity when we refer to an event we are not talking about an event of the .NET event-delegate type; in the context of your bot an event could be walking into a wall or hearing a noise.
</p>
<p>It is also possible to override the behaviour of the methods which receive the messages passed in by the server so that your bot can respond sensibly to them. For example, you can override the&nbsp;<strong>AnotherBotDied
</strong>method to keep a scoreboard of who's winning and losing in the game. For full details on these methods please check the
<a href="http://www.net.dcs.hull.ac.uk/utbot/APIDoc/index.html">API reference</a>.
</p>
<p><strong>The creation of a working bot</strong><br>
The following examples have been provided as a basic starting point for developing your own working bot. Please note these examples are by no means the best way to do things; it is up to you to optimize your bot to make the best fragger.
</p>
<p><strong>Creating your Bot<br>
</strong>After installing the Project Template from the Getting Started section, open up Visual Studio Express and select File...New Project... and select the &quot;UT Remote Bot&quot; template.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image06.png"><img height="376" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image0_thumb4.png" width="640" border="0"></a>
</p>
<p>&nbsp;</p>
<p><strong>Solution Explorer View</strong></p>
<p>Here you'll see the solution explorer view of the UT Remote Bots which contains a number of files for the project. In essence, the UT RemoteBot project is nothing more than a console application that sends and receives commands at a specific interval</p>
<ul>
<li><strong>Starter </strong>file- The basic template that describes the Remote UserBot and the server
</li><li><strong>RemoteUserBot</strong> file - Where you will code all of the work </li><li><strong>UTRemoteBot.dll</strong> - The class library that contains the wrapper code for Unreal Tournament Functions
</li><li><strong>UTBotsVisualiser.exe</strong> - The visualiser tool mentioned previously
</li><li><strong>UT Bots - Guide.htm</strong> - An HTML getting started guide</li></ul>
<p><strong><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image010.png"><img height="198" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image0_thumb6.png" width="182" border="0"></a>
</strong></p>
<p><strong>Starter File<br>
</strong>The Starter file is a console application that creates an instance of the RemoteUserBot class. You can customize it by providing a name for your bot, currently &quot;UserBot&quot;, a &quot;skin&quot; for your bot which will display how your bot appears (ex: mercenary
 vs alien), the bot color (for teams), and the server to connect to. If you are self-hosting, you should set the server value to: &quot;127.0.0.1&quot;
</p>
<p><strong>Visual Basic</strong> </p>
<pre class="csharpcode"><span class="kwrd">Imports</span> UTRemoteBot

<span class="kwrd">Module</span> Starter
    <span class="rem">'''&lt;summary&gt;</span>
    <span class="rem">''' The main entry point for this bot. </span>
    <span class="rem">'''Creates a new instance of your bot which will connect to the server and begin to play</span>
    <span class="rem">'''&lt;/summary&gt;</span>
    <span class="kwrd">Sub</span> Main()
        <span class="kwrd">Dim</span> b <span class="kwrd">As</span> RemoteUserBot = <span class="kwrd">New</span> RemoteUserBot(<span class="str">&quot;UserBot&quot;</span>, BotSkin.Blake, BotColour.None, <span class="str">&quot;classroom.dcs.hull.ac.uk&quot;</span>)
        Console.WriteLine(<span class="str">&quot; (Press Enter To Disconnect)&quot;</span> &amp; Microsoft.VisualBasic.Chr(10) &amp; <span class="str">&quot;&quot;</span>)
        Console.Read()
        b.DisconnectFromServer()
        Console.Read()
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">End</span> <span class="kwrd">Module</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>Visual C#</strong></p>
<pre class="csharpcode"><span class="kwrd">using</span> System;

<span class="kwrd">namespace</span> UTRemoteBot
{

    <span class="kwrd">public</span> <span class="kwrd">class</span> Starter
    {

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// The main entry point for this bot. </span>
        <span class="rem">/// Creates a new instance of your bot which will connect to the server and begin to play</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [STAThread]
        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Main()
        {
            RemoteUserBot b = <span class="kwrd">new</span> RemoteUserBot(<span class="str">&quot;UserBot&quot;</span>, BotSkin.Blake, BotColour.None, <span class="str">&quot;classroom.dcs.hull.ac.uk&quot;</span>);

            Console.WriteLine(<span class="str">&quot; (Press Enter To Disconnect)\n&quot;</span>);
            Console.Read();

            b.DisconnectFromServer();
            Console.Read();
        }

    }
}
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you run the program now you will find that your bot will appear in the game and stand waiting for instructions. The game framework is calling the PerformActions method in your bot at regular intervals, but because the method presently does nothing, your
 bot does not move. </p>
<p>The next thing we must do is change the content of this method to get control of our bot and make it move around in the game by adding code to the
<strong>RemoteUserBot </strong>file. Opening up the RemoteUserBot file shows the code below where we will add whatever code we want to perform directly into the
<strong>PerformActions() </strong>method. </p>
<p><strong>RemoteUserBot Visual Basic</strong> </p>
<pre class="csharpcode"><span class="kwrd">Imports</span> System
<span class="kwrd">Imports</span> System.Collections.Generic
<span class="kwrd">Imports</span> UTRemoteBot


<span class="kwrd">Public</span> <span class="kwrd">Class</span> RemoteUserBot
    <span class="kwrd">Inherits</span> RemoteBot
    <span class="rem">''' &lt;summary&gt;</span>
    <span class="rem">''' This methods creats an instance of your bot sets the UT options such as name, colour and </span>
    <span class="rem">''' skin and then connects to the specified server. Once connected PerformActions will be </span>
    <span class="rem">''' called every ~2 seconds and any in game events such as hitting a wall will call the appropiate</span>
    <span class="rem">''' overriden method.</span>
    <span class="rem">''' &lt;/summary&gt;</span>
    <span class="rem">''' &lt;param name=&quot;aName&quot;&gt;Name of your bot as it should appear in game&lt;/param&gt;</span>
    <span class="rem">''' &lt;param name=&quot;skin&quot;&gt;Skin that the bot should use in game&lt;/param&gt;</span>
    <span class="rem">''' &lt;param name=&quot;colour&quot;&gt;Colour of the bot in game&lt;/param&gt;</span>
    <span class="rem">''' &lt;param name=&quot;server&quot;&gt;The server which to connect either an IP address or a host name, it can only connect on the default port&lt;/param&gt;</span>
    <span class="rem">''' &lt;remarks&gt;&lt;/remarks&gt;</span>
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>(<span class="kwrd">ByVal</span> aName <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> skin <span class="kwrd">As</span> BotSkin, <span class="kwrd">ByVal</span> colour <span class="kwrd">As</span> BotColour, <span class="kwrd">ByVal</span> server <span class="kwrd">As</span> <span class="kwrd">String</span>)
        <span class="kwrd">MyBase</span>.<span class="kwrd">New</span>(aName, skin, colour, server)

    <span class="kwrd">End</span> <span class="kwrd">Sub</span>

    <span class="rem">''' &lt;summary&gt;</span>
    <span class="rem">''' Method to control the bot once it has connected to the server</span>
    <span class="rem">''' &lt;/summary&gt;</span>
    <span class="rem">''' &lt;remarks&gt;&lt;/remarks&gt;</span>
    <span class="kwrd">Protected</span> <span class="kwrd">Overloads</span> <span class="kwrd">Overrides</span> <span class="kwrd">Sub</span> PerformActions()
        <span class="rem">'Add code here to perform an action at a specific interval</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> Class</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>RemoteUserBot Visual C#</strong> </p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;

<span class="kwrd">namespace</span> UTRemoteBot
{
    <span class="kwrd">public</span> <span class="kwrd">class</span> RemoteUserBot : RemoteBot
    {
        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// This methods creats an instance of your bot sets the UT options such as name, colour and </span>
        <span class="rem">/// skin and then connects to the specified server. Once connected PerformActions will be </span>
        <span class="rem">/// called every ~2 seconds and any in game events such as hitting a wall will call the appropiate</span>
        <span class="rem">/// overriden method.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="rem">/// &lt;param name=&quot;aName&quot;&gt;Name of your bot as it should appear in game&lt;/param&gt;</span>
        <span class="rem">/// &lt;param name=&quot;skin&quot;&gt;Skin that the bot should use in game&lt;/param&gt;</span>
        <span class="rem">/// &lt;param name=&quot;colour&quot;&gt;Colour of the bot in game&lt;/param&gt;</span>
        <span class="rem">/// &lt;param name=&quot;server&quot;&gt;The server which to connect either an IP address or a host name, it can only connect on the default port&lt;/param&gt;</span>
        <span class="rem">/// &lt;remarks&gt;&lt;/remarks&gt;</span>
        <span class="kwrd">public</span> RemoteUserBot(<span class="kwrd">string</span> aName, BotSkin skin, BotColour colour, <span class="kwrd">string</span> server)
            : <span class="kwrd">base</span>(aName, skin, colour, server)
        {
        }


        <span class="rem">//Method to control the bot once it has connected to the server</span>
        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> PerformActions()
        {
            <span class="rem">//Add code here to perform an action at a specific interval</span>

        }
    }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>Bot's first sight</strong><br>
Now that we have a bot in the game we need to make it actually do something. The first thing we are going to make it do is move to a NavPoint. This is a location in the game which might hold something interesting. A series of NavPoints provides a path through
 the level to interesting items. A bot can travel around a game level by moving from one NavPoint to another.
</p>
<p>Within the game framework (UTRemoteBot.dll),&nbsp;an instance of the UTVector class can be used to express the actual location of something. The location of a Navpoint is given by its Location property, which is given as a UTVector value.
</p>
<p>Our bot needs to have a way of keeping track of where it is going so in the RemoteUserBot class create a new private UTVector called destinationLocation:
</p>
<p><strong>VB</strong> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> destinationLocation <span class="kwrd">As</span> UTVector</pre>
<pre class="csharpcode">&nbsp;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong> </p>
<pre class="csharpcode"><span class="kwrd">private</span> UTVector destinationLocation; </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We want our bot to head towards the first navpoint that it “sees”. To do this we place the following code into the
<strong>PerformActions</strong>() method. </p>
<p><strong>VB</strong> </p>
<pre class="csharpcode"><span class="kwrd">Me</span>.destinationLocation = <span class="kwrd">Me</span>.CurrentGameState.NavPointsVisible(0).Location</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong> </p>
<pre class="csharpcode"><span class="kwrd">this</span>.destinationLocation = <span class="kwrd">this</span>.CurrentGameState.NavPointsVisible[0].Location; </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>CurrentGameState </strong>property of our bot contains information on the current state of the game.
<strong>NavPointsVisible</strong> is an array of references to UTVector instances which refer to all of the NavPoints a Bot can see. The above code simply takes the UTVector at position 0 (the first NavPoint your Bot can see) and sets destinationLocation to
 refer to it. </p>
<p>So at this point the bot has identified the location it wants to move towards, now we have to make it move in that direction.
</p>
<p><strong>Bot's first steps </strong><br>
Now we are going to make our bot move to the destination it has selected. Place the following code into the
<strong>PerfomActions() </strong>method just below the code written in the previous example.
</p>
<p><strong>VB</strong> </p>
<pre class="csharpcode"><span class="kwrd">Me</span>.BotCommands.RunTo(<span class="kwrd">Me</span>.destinationLocation)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong> </p>
<pre class="csharpcode"><span class="kwrd">this</span>.BotCommands.RunTo(<span class="kwrd">this</span>.destinationLocation); </pre>
<pre class="csharpcode">&nbsp;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>BotCommands </strong>provides a set of methods which are the commands that your program can give to the bot. There are a wide range of commands, some of which are listed below. For full details you should investigate the
<a href="http://www.net.dcs.hull.ac.uk/utbot/APIDoc/index.html">API reference</a>.
</p>
<ul>
<li><strong>ChangeWeapon()</strong> - Changes the current weapon </li><li><strong>Jump()</strong> - Jumps in the air </li><li><strong>RotateBy()</strong> - Rotates by a specific degree </li><li><strong>RunTo()</strong> - Runs to a specific location </li><li><strong>Shoot()</strong> - Attacks a target or location </li><li><strong>StopShooting()</strong> - Stops the bot from shooting </li><li><strong>StrafeTo()</strong> - Strafes to a specific location</li></ul>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image015.png"><img height="233" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image0_thumb9.png" width="290" border="0"></a>
</p>
<p>The <strong>RunTo()</strong> command is provided with a destination location. When this method is called your bot will start running towards the destination.
</p>
<p>If you execute this program you will see your bot start running towards a navpoint.
</p>
<p><strong>Bot's first shot</strong><br>
For the purpose of this example we will next make our bot shoot at the location it is running towards, it is recommended that you change this when creating your own implementation as shooting at an empty NavPoint is unlikely to get you many frags.
</p>
<p>Place the following code into the <strong>PerfomActions() </strong>method just below the code written in the previous example.
</p>
<p><strong>VB</strong> </p>
<pre class="csharpcode"><span class="kwrd">Me</span>.BotCommands.Shoot(<span class="kwrd">Me</span>.destinationLocation, <span class="kwrd">false</span>)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong> </p>
<pre class="csharpcode"><span class="kwrd">this</span>.BotCommands.Shoot(<span class="kwrd">this</span>. destinationLocation, <span class="kwrd">false</span>); </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you execute the program you will see that your bot now shoots at the location as it runs towards it. It will continue doing this until you call a method to instruct it to stop.
</p>
<p>Place the following code into the <strong>PerfomActions() </strong>method just below the code written in the previous step. Your Bot will now stop shooting.
</p>
<p><strong>VB</strong> </p>
<pre class="csharpcode"><span class="kwrd">Me</span>.BotCommands.StopShooting</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong> </p>
<pre class="csharpcode"><span class="kwrd">this</span>.BotCommands.StopShooting(); </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>Viewing your bot in action</strong><br>
You can find out what your bot is up to we have provided a visualiser. This is a modified version of TclViz. When you run the Visualiser you can connect it to any server running the mutator and get a birds eye view of the game in progress by simply providing
 the IP address of the server. You can see the waypoints which are marked by pink dots and the active players which have their name next to a yellow dot and a line indicating which way they are facing. From here you can view the game and see what your bot is
 doing as shown in the visualizer screenshot. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image019.png"><img height="384" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1719502/image0_thumb11.png" width="325" border="0"></a>
</p>
<p>&nbsp;</p>
<p><strong>What to do next</strong><br>
Now that you have got your bot into the game and made it move around a bit you can start thinking about making it into a decent player of the game. Take a look at the other members of the NavPoint class so that your bot can look for weapons and health pack
 and move towards them. Then take a look at the members of the CurrentGameState class for the information that your bot is given about the game around it.
</p>
<p>One thing you will need to add is some way that your bot can be in a particular state at any given time. Sensible states might be “Roaming”, “Hunting”, “Idle”, “Recovering” etc. Depending on the state your bot is in it will do different things each time
 PerformActions is called. </p>
<p>If it is in the roaming state it will be looking for a nav point. If it is in the hunting state it will be chasing other bots. If it is in the recovering state it will be avoiding other bots and looking for a MediPac, and so on. You can keep track of the
 state of your bot by creating an enumerated type with the different values. Then your PerformActions method can contain a switch statement which makes it behave differently, depending on what it is doing.
</p>
<p>A state machine is just one way you could program your AI, you could make a sophisticated bot that had a way of determining if a result had a positive or negative consequence and then have the bot perform more actions that had a positive consequence. Essentially
 a learning bot, be careful though if your bot takes too long executing PerformActions it will get out of touch with the game as messages will sit on the queue unprocessed waiting for your code to finish.
</p>
<p>There are also some very handy hints in the FAQ below about getting your bot on the road to stardom.
</p>
<p><strong></strong>&nbsp;</p>
<p><strong>Conclusion<br>
</strong>With this you should be able to go about creating your own deathmatch player. If you have any questions which are not answered in the FAQ below feel free to use the forum on the site (<a href="http://www.net.dcs.hull.ac.uk/utbot/">http://www.net.dcs.hull.ac.uk/utbot/</a>
 ). </p>
<p>If you're feeling particularly brave join our project on CodePlex at <a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=UTBots">
http://www.codeplex.com/Wiki/View.aspx?ProjectName=UTBots</a> and help pitch in with improving the client.
</p>
<p><strong></strong>&nbsp;</p>
<p><strong>Frequently Asked Questions</strong> </p>
<h3></h3>
<strong></strong>
<p><strong>Do I need Unreal Tournament to use this stuff?</strong><br>
No, you can create bots and have them connect to any bot server and use the visualiser to get an idea of what's going on. Of course it isn't as pretty as UT! You can also run the server without owning a copy as Epic distribute a free server side runtime which
 you can get from <a href="http://www.fileshack.com/file.x?fid=300">http://www.fileshack.com/file.x?fid=300</a> .
</p>
<p><strong>My bot won't move! What did I do wrong?<br>
</strong>This could be due to incorrect programming logic, please double check your code. You may also have left a Break Point within Visual Studio, if this is reached while watching your bot via Unreal Tournament your bot will appear to freeze until your program
 continues. </p>
<p><strong>My bot keeps getting stuck when it runs into a wall. How can I stop this?<br>
</strong></p>
<p>Try overriding the HitWall() method, an example of how to do this would be:<br>
<strong>VB</strong></p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">Protected</span> <span class="kwrd">Overrides</span> <span class="kwrd">Sub</span> HitWall(<span class="kwrd">ByVal</span> locationOfBot <span class="kwrd">As</span> UTVector, <span class="kwrd">ByVal</span> normalOfCollision <span class="kwrd">As</span> UTVector)
<span class="kwrd">  Me</span>.BotCommands.RotateBy(90)
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong></p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> HitWall(UTVector locationOfBot, UTVector normalOfCollision)
{
<span class="kwrd">  this</span>.BotCommands.RotateBy(90);
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><br>
This method will be called when your bot hits the wall. The code above will simply rotate the bot by ninety degrees when it hits a wall.
</p>
<p><strong>What events can my bot react to?<br>
</strong>You can try overriding any of the following methods: </p>
<ul>
<li>AnotherBotDied() </li><li>BumpedActor() </li><li>HitLedge() </li><li>HeardNoise() </li><li>HeardPickup() </li><li>HitWall() </li><li>IncomingProjectile() </li><li>NewGlobalChatMessage() </li><li>PathReceieved() </li><li>PickedUpItem() </li><li>ShotAnotherBot() </li><li>TookDamage() </li><li>WasKilled() </li></ul>
<p><strong>My Bot seems a little slower than the other Bots! How do I make it faster?</strong><br>
Try improving your Bot's logic to optimize the speed. </p>
<p>The more quickly the <strong>PerformActions()</strong> method completes the more time your bot has to react in the game.
</p>
<p><strong>My Bot is nearly dead! How do I get it to collect some health? <br>
</strong>A simple idea would be to just run your bot around the level, checking the CurrentGameState.ItemsVisible list to see if your bot can see a Health item and if it can, get it to run to that location to collect it.
</p>
<p>Another idea would be to use the GetNearestItem() method inside the LevelMap class to find the location of the closest MediPack. Then you can call the
<strong>GetPathTo() </strong>method from the BotCommands class to ask for an array of UTNavPoints to get to that health box. Once you have received this path, you can just get your bot to run to each point in turn until it reaches the health.
</p>
<p>The following example shows you how you could do this: </p>
<p><strong>VB</strong> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> pathToRun() <span class="kwrd">As</span> UTNavPoint
<span class="kwrd">Dim</span> index <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 0

    
    <span class="kwrd">Protected</span> <span class="kwrd">Overrides</span> <span class="kwrd">Sub</span> PerformActions()
        <span class="rem">'Check to see if we have a path to run already</span>
        <span class="kwrd">If</span> (<span class="kwrd">Not</span> (<span class="kwrd">Me</span>.pathToRun) <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">Then</span>
            <span class="rem">'Run to this point on the path</span>
            <span class="kwrd">Me</span>.BotCommands.RunTo(<span class="kwrd">Me</span>.pathToRun(index))
            <span class="rem">'Check to see if our bot is near to the point we are running to</span>
            <span class="kwrd">If</span> <span class="kwrd">Me</span>.Self.IsCloseTo(<span class="kwrd">Me</span>.pathToRun(index)) <span class="kwrd">Then</span>
                <span class="rem">'Move our index to the next point in the path array</span>
                index = (index &#43; 1)
                <span class="kwrd">If</span> (index &gt;= <span class="kwrd">Me</span>.pathToRun.Length) <span class="kwrd">Then</span>
                    <span class="rem">'The index has reached the end of the path.</span>
                    <span class="kwrd">Me</span>.pathToRun = <span class="kwrd">Nothing</span>
                <span class="kwrd">End</span> <span class="kwrd">If</span>
            <span class="kwrd">Else</span>
                <span class="rem">'We don't have a path so find the nearest health box</span>
                <span class="kwrd">Dim</span> box <span class="kwrd">As</span> UTObject = <span class="kwrd">Me</span>.LevelMap.GetNearestItem(HealthType.MediBox)
                <span class="rem">'Ask for a path to that box</span>
                <span class="kwrd">Me</span>.BotCommands.GetPathTo(<span class="str">&quot;Looking for health&quot;</span>, box)
            <span class="kwrd">End</span> <span class="kwrd">If</span>
        <span class="kwrd">End</span> <span class="kwrd">If</span>
        <span class="rem">'Override this method to collect the result back from GetPathTo()</span>
        <span class="kwrd">Dim</span> PathReceieved <span class="kwrd">As</span> System.Void
        <span class="kwrd">string</span>
        requestID
        <span class="kwrd">Dim</span> path() <span class="kwrd">As</span> UTNavPoint
        <span class="kwrd">If</span> (requestID = <span class="str">&quot;Looking for health&quot;</span>) <span class="kwrd">Then</span>
            <span class="rem">'The server has sent us a path so store it in our variable</span>
            <span class="kwrd">Me</span>.pathToRun = path
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>

</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>C#</strong> </p>
<pre class="csharpcode"><span class="rem">//Some variables to store our data</span>
UTNavPoint[] pathToRun;
<span class="kwrd">int</span> index = 0; 

<span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> PerformActions()
{
<span class="rem">  //Check to see if we have a path to run already</span>
<span class="kwrd">  if</span> (<span class="kwrd">this</span>.pathToRun != <span class="kwrd">null</span>)
  {
<span class="rem">     //Run to this point on the path</span>
<span class="kwrd">     this</span>.BotCommands.RunTo(<span class="kwrd">this</span>.pathToRun[index]); 

<span class="rem">  //Check to see if our bot is near to the point we are running to</span>
<span class="kwrd">  if</span> (<span class="kwrd">this</span>.Self.IsCloseTo(<span class="kwrd">this</span>.pathToRun[index]))
  {
<span class="rem">    //Move our index to the next point in the path array</span>
    index&#43;&#43;;
<span class="kwrd">    if</span> (index &gt;= <span class="kwrd">this</span>.pathToRun.Length)
    {</pre>
<pre class="csharpcode">      <span class="rem">//The index has reached the end of the path.</span>
<span class="kwrd">      this</span>.pathToRun = <span class="kwrd">null</span>;
    }
  }
<span class="kwrd">  else</span>
  {
<span class="rem">    //We don't have a path so find the nearest health box</span>
    UTObject box = <span class="kwrd">this</span>.LevelMap.GetNearestItem(HealthType.MediBox); <span class="rem">//Ask for a path to that box</span>
<span class="kwrd">    this</span>.BotCommands.GetPathTo(<span class="str">&quot;Looking for health&quot;</span>, box);
  }
} 

<span class="rem">//Override this method to collect the result back from GetPathTo()</span>
<span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> PathReceieved(<span class="kwrd">string</span> requestID, UTNavPoint[] path)
{
<span class="kwrd">  if</span> (requestID == <span class="str">&quot;Looking for health&quot;</span>)
  {
<span class="rem">    //The server has sent us a path so store it in our variable</span>
<span class="kwrd">    this</span>.pathToRun = path;
  }
} 
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><strong>Some of the methods want me to provide a HealthType, AmmoType, etc as a parameter. Where can I find these?<br>
</strong>These types are Enumerators which have been used to make coding your bot easier. They are all located inside the
<strong>UTRemoteBot</strong> namespace so to use them you need only type in the appropriate name and IntelliSense should fill in the rest.
</p>
<p>For example typing WeaponType. Would fill the Intellisense with the different types of weapons in UT so you could then pass these to the LevelMap.GetNearestItem() method.
</p>
<p>These types can all be sent as parameters to various methods in the BotCommands class:
</p>
<ul>
<li>AmmoType – A list of all the types of ammo for weapons in the game </li><li>ArmourType – A list of all the types of armour in the game </li><li>HealthType – A list of the different types of health items in the game </li><li>WeaponType – A list of the different types of weapon in the game </li></ul>
<p>&nbsp;</p>
<p>The following types can be sent as parameters to your bot's constructor in the Starter file:<br>
</p>
<ul>
<li>BotColour – A list of the 5 different colours to use when customising your bot in the Starter file
</li><li>BotSkin – A list of the skins that you can give your bot when customising it in the Starter file
</li><li>OutputType – The level of output you want to be written to the console when developing your bot</li></ul>
<p><strong>How do I shoot at another player? </strong></p>
<p>All you need do is check the <strong>CurrentGameState.PlayersVisible</strong> list for any players visible. You would then call the
<strong>BotCommands.Shoot()</strong> passing in one of the Bots from the list and a bool which if set to true your bot will use the secondary fire mode on the current weapon if set to false your bot will use the primary fire mode.
</p>
<p><strong>GetPathTo doesn't seem to work <br>
</strong>For reasons best known to code pixies GetPathTo doesn't always return a valid navigation path. In some cases it might even return nothing. The root cause of this problems lies deep within the Unreal Tournament path finding routines. It seems that in
 certain circumstances, for instance just after an item has been collected, the game just can't find a path. We strongly recommend that your bot doesn't rely too heavily on this method and only uses it occasionally with plenty of error checking!
</p>
<p><strong>Where do I connect to?</strong><br>
You can find a list of servers here: <a href="http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx">
http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx</a>&nbsp; or you can run your own instructions for which can be found here:
<a href="http://www.net.dcs.hull.ac.uk/utbot/ServerSetup.aspx">http://www.net.dcs.hull.ac.uk/utbot/ServerSetup.aspx</a>
</p>
<p><strong></strong>&nbsp;</p>
<p><strong>I want to run my own server</strong><br>
Great! Instructions and files can be found at: <a href="http://www.net.dcs.hull.ac.uk/utbot/ServerSetup.aspx">
http://www.net.dcs.hull.ac.uk/utbot/ServerSetup.aspx</a> </p>
<p>If your server is public and you don't mind strangers you can add it to the list here:
<a href="http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx">http://www.net.dcs.hull.ac.uk/utbot/ServerList.aspx</a>
</p>
<p><strong>Is Unreal Tournament Game of the Year Edition the only supported UT version?<br>
</strong>Yes, although we are looking to add support for Unreal Tournament 2007 when it is released. Check the CodePlex
<a href="http://www.codeplex.com/UTBots">Unreal Tournament Bots</a> project for more information</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:27e10f6ead4040a8afd69e7600d5e7f5">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Creating-NET-AI-Bots-for-Unreal-Tournament</comments>
      <itunes:summary>




Have you ever played a first person shooter? Then you&#39;ve probably played against computer controlled players known as &amp;quot;bots&amp;quot; which are computer programs designed with artificial intelligence. Up until now the only
 way to do create your own bot for a game like Unreal Tournament was to learn a bunch of C&amp;#43;&amp;#43; and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express.




Andy Sterland (Program Manager, Microsoft),James Lissiak, and Tom Randell

Difficulty: Intermediate
Time Required: 
Less than 1 hour
Cost: Less Than $50
Software: Visual Basic or Visual C# Express Editions required, optionally install client and server piece:
optional install of Unreal Tournament Game of the Year Edition client,
optional Unreal Tournament Server Software
Hardware: None
Download: Download








Video: Programming Unreal Tournament AI bots
Unreal Tournament &amp;quot;Bots&amp;quot;
&amp;nbsp; 
&amp;nbsp; 
Have you ever played a first person shooter? Then you&#39;ve probably played against computer controlled players&amp;nbsp;known as &amp;quot;bots&amp;quot; which are computer programs designed with artificial intelligence. Up until now the only way to do create your own bot for a game
 like Unreal Tournament was to learn a bunch of C&amp;#43;&amp;#43; and complicated AI routines. Of course, what you really want to do is code up your bot using C# or VB and Visual Studio Express.
 
For this project, we created: 

VB and C# project templates to simplify setup/installation of the necessary components for Visual Studio Express
A&amp;nbsp;&amp;quot;Bot API mutator&amp;quot; (custom level) which runs on the server that can accept&amp;nbsp;.NET bots
A&amp;nbsp;&amp;quot;visualizer&amp;quot; (custom Windows Form app) which provides a visual representation of a map so you can watch players play against each other
This project uses the code based on the Mutator for Unreal Tournament at 
http://www.planetunreal.com/gamebots/, but instead&amp;nbsp;creates a .NET wrapper you to </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Creating-NET-AI-Bots-for-Unreal-Tournament</link>
      <pubDate>Mon, 19 Feb 2007 20:37:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Creating-NET-AI-Bots-for-Unreal-Tournament</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1719502_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1719502_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Andy Sterland </dc:creator>
      <itunes:author>Andy Sterland </itunes:author>
      <slash:comments>25</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Creating-NET-AI-Bots-for-Unreal-Tournament/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Intro to XNA Part 1: Building Tiny Tennis</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" colspan="2"><span class="entry_description">In this article, the ZMan walks through creating Tiny Tennis, a Pong clone, using the XNA Framework</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">The ZMan</div>
<div class="entry_company"><a href="http://www.thezbuffer.com/">TheZbuffer.com</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/download/">Visual C# Express
</a>, <a href="http://msdn.com/xna/">XNA Game Studio Express</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=265223">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>December 11th... a day that we all hope will go down in history as the start of a new generation of hobbyist game developers. Today
<a href="http://msdn.com/xna">XNA Game Studio Express</a> launches. It's not the first platform to allow home developers access to console development but its is the first one to be fully sanctioned and supported and running on a retail console.
</p>
<p>So where do you start? XNA Game Studio Express is going to interest people who have no game development experience at all so starting with some simple games is a good idea. You may have seen the 3 games I did for MSDN for their Upgrade Your Game promotion
 - <a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/10/31/916355.aspx">
Tiny Tennis</a>, <a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/10/31/916430.aspx">
Space Blitz</a> and <a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044573.aspx">
Crusader</a>. For this series of articles I will walk you through simple XNA applications using as much code from these starter kits as possible. The original tutorials and screencasts will walk you through the game logic and these articles will add in the
 XNA know how.</p>
<p>Firstly a couple of points:</p>
<ol>
<li>Even The ZMan didn't have access to the retail XBox 360 release before today so for the first part I will only cover the PC. Watch for part 2 to add in the things needed to run on the 360 and go into more detail.
</li><li>XNA only supports Visual C# Express so although the original games were in Visual Basic, this series will be only in C#
</li><li>You need to ensure you have <a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/">
C# Express</a> and <a href="http://msdn.microsoft.com/xna">XNA Game Studio Express</a> installed. If you have problems installing or running then ask in the
<a href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=882&amp;SiteID=1">XNA Game Studio Express Forum</a>.
</li></ol>
<h1>Making a new XNA game</h1>
<p>Installing XNA Game Studio Express adds several new project types to C# Express:</p>
<p><img title="New Project" height="469" alt="New Project" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1256876/NewProject4.png" width="681">
</p>
<p>The SpaceWar projects are complete games for the xbox and the windows platforms - they have all the source code, graphics and sound and
<a href="http://letskilldave.com/archive/2006/11/14/Show-me-your-Spacewar-mods_21002100_.aspx">
Microsoft absolutely want you to use this</a> to make your own games as well as learn about making simple 2d and 3d games.</p>
<p>The Windows Game and Xbox Game projects are for writing games on those 2 platforms and the Game Library projects are for making
<span>reusable </span>components that are easy to use within the XNA game projects.</p>
<p>For this tutorial start with the Windows Game project. Once you have selected it you can
<span>immediately </span>run the project and see a <span>wonderful </span>cornflower blue, blank screen. (It is widely speculated that cornflower blue is Tom Miller's
<span>favorite </span>color).</p>
<p>Now we need to add the project files from the Tiny Tennis sample. Select Add Files by right clicking the project and then browse to the Tiny Tennis solution and add the following files:</p>
<p><img title="Add Exiisting Item" height="346" alt="Add Exiisting Item" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1256876/AddFiles5.png" width="529">
</p>
<h1>Converting the Game</h1>
<p>There are going to be a LOT of errors right now because Tiny Tennis relies heavily on Windows.Forms and System.Drawing neither of which are available when writing an XNA application that you eventually want to run on the Xbox 360 because the Xbox 360 does
 not support those libraries. So initially there are several big changes to make.
</p>
<p>Game1.cs is the main XNA game file. It contains the initializer for the game as well as several methods that are called automatically for the game. If you have been through the tutorials for the Express games you will see that the games are designed to be
 continually updated. As fast as possible the keyboard is read, the positions are updated and the screen is redrawn. This is exactly the same method used in XNA so it is very simple for us to use the same logic.</p>
<p>You need to copy sections of code from the tennis.cs file into the game1.cs. </p>
<p>Firstly the declarations:</p>
<div class="code">private Bat _player1;<br>
private Bat _player2;<br>
private Ball _ball;<br>
private GameState gameState; </div>
<p>Then the constructor which goes into the end of the Game1 constructor.</p>
<div class="code">gameState = new GameState();<br>
<br>
//Create&nbsp;the&nbsp;bat&nbsp;Sprites&nbsp;-&nbsp;they&nbsp;need&nbsp;the&nbsp;keyboard&nbsp;controls&nbsp;and&nbsp;the&nbsp;gameplay&nbsp;area&nbsp;limits<br>
_player1 = new Bat(player1Bat,&nbsp;30,&nbsp;Keys.Q,&nbsp;Keys.A,&nbsp;0, ClientSize.Height);<br>
<br>
//use&nbsp;this&nbsp;line&nbsp;for&nbsp;a&nbsp;second&nbsp;human&nbsp;player<br>
//_player2&nbsp;=&nbsp;new&nbsp;Bat(player2Bat,&nbsp;ClientSize.Width&nbsp;-&nbsp;30&nbsp;-&nbsp;Bat.Width,&nbsp;Keys.P,&nbsp;Keys.L,&nbsp;0,&nbsp;ClientSize.Height);<br>
<br>
//use&nbsp;this&nbsp;line&nbsp;for&nbsp;a&nbsp;computer&nbsp;player<br>
_player2 = new Bat(player2Bat, ClientSize.Width - 30 - Bat.Width, &nbsp;0, ClientSize.Height);<br>
<br>
//Create&nbsp;the&nbsp;ball&nbsp;sprite.&nbsp;It&nbsp;needs&nbsp;the&nbsp;gameplay&nbsp;area&nbsp;limits&nbsp;and&nbsp;references&nbsp;to&nbsp;the&nbsp;bats&nbsp;to&nbsp;be&nbsp;able&nbsp;to&nbsp;check&nbsp;for&nbsp;collisions<br>
_ball = new Ball(ballControl,&nbsp;0,&nbsp;ClientSize.Width,&nbsp;0,&nbsp;ClientSize.Height,&nbsp;_player1,&nbsp;_player2,&nbsp;gameState);<br>
<br>
//Connect&nbsp;the&nbsp;AI&nbsp;player&nbsp;with&nbsp;the&nbsp;ball<br>
_player2.Ball&nbsp;= _ball; </div>
<p>The TinyTennis_Paint code gets moved into the Draw method in Game1.cs. The Draw method is continually called by the XNA Game class and this is where you should draw your graphics.</p>
<div class="code">//Perform any animation<br>
_player1.Update(gameTime, elapsedTime);<br>
_player2.Update(gameTime, elapsedTime);<br>
_ball.Update(gameTime, elapsedTime);<br>
<br>
//Draw the scores<br>
player1Score.Text = gameState.Player1Score.ToString();<br>
player1Score.Refresh();<br>
player2Score.Text = gameState.Player2Score.ToString();<br>
player2Score.Refresh();<br>
<br>
//and the game objects<br>
_player1.Draw();<br>
_player2.Draw();<br>
_ball.Draw(); </div>
<p>Notice that I have not copied across any of the timer/stopwatch code. XNA provides its own timer logic so that is not needed. Since XNA does not support Windows forms, it does not support KeyUp and KeyDown events so the code for those is of no use to us.
 You can now remove TinyTennis.cs from the project.</p>
<p>Now to fix up the errors. If you hit compile and walk through them one by one you will fix them in the following order:</p>
<ul>
<li>The first thing to do is remove all the 'using' statements that mention Windows.Forms and System.Drawing. If you try to compile these will be the first errors on the list.
</li><li>PointF in System.Drawing is replaced by Vector2 in Microsoft.XNA.Framework. If you change the type to Vector2 you can use the intellisense feature of C# express to add in the new using statement.<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1256876/using8.png"><img height="90" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1256876/using_thumb6.png" width="341" border="0"></a> &nbsp;
</li><li>There is no SizeF type in XNA. Since it is just a pair of values you can reuse Vector2 type so change SizeF to Vector2. Change the Width property to X and the Height
</li><li>Color in System.Drawing is replaced by Color in Microsoft.XNA.Framework. For most of these errors you just need to add the correct using statement with intellisense.
</li><li>In TinyTennis I used windows controls to do the rendering. Since this is not possible in XNA all references to the Control type need to be removed
<ul>
<li>in ball.cs and bat.cs remove the parameters in the constructor that refer to Control
</li><li>ControlSprite is a wrapper around Sprite that draws using windows controls. Since we no longer have windows controls we can remove ControlSprite from the project and just use the Sprite implementation
</li><li>Now that ControlSprite is missing Ball and Bat should be changed to inherit directly from Sprite
</li><li>In game1.cs remove the Control parameters from the new Bat() and new Ball() lines in the constructor
</li></ul>
</li><li>Keys is now found in Microsoft.Xna.Framework.Input so needs the correct using statement
</li><li>ClientSize from Windows.Forms becomes Window.ClientBounds from Microsoft.Xna.Framework
</li><li>In the WindowsForms version of TinyTennis I tracked the game time myself. This code is redundant in XNA and is removed
<span>because </span>the Game class passes in gametime to the Draw() function. So replace the elapsedTime property with gameTime.ElapsedGameTime.TotalSeconds and the gameTime parameter with gameTime.TotalGameTime.TotalSeconds<br>
<div class="code">//Perform any animation<br>
_player1.Update(gameTime.TotalGameTime.TotalSeconds, gameTime.ElapsedGameTime.TotalSeconds);<br>
_player2.Update(gameTime.TotalGameTime.TotalSeconds, gameTime.ElapsedGameTime.TotalSeconds);<br>
_ball.Update(gameTime.TotalGameTime.TotalSeconds, gameTime.ElapsedGameTime.TotalSeconds);
</div>
</li><li>There is no easy way to draw text to the screen in XNA. So for this article I am simply going to avoid the subject until there is time to go into it in more detail. Comment out the lines that display the score. You can use the ctrl-K-C keypress to easily
 to this. ctrl-K-U reverses it<br>
<div class="code">//Draw the scores<br>
//player1Score.Text = gameState.Player1Score.ToString();<br>
//player1Score.Refresh();<br>
//player2Score.Text = gameState.Player2Score.ToString();<br>
//player2Score.Refresh(); </div>
</li><li>Since the Point type uses integers in XNA there are some parameters to change to int from float and the calculations need to have their results cast into (int). For example:<br>
<div class="code">public virtual void Update(double gameTime, double elapsedTime)<br>
{<br>
&nbsp; &nbsp; //Move the sprite based on the velocity<br>
&nbsp; &nbsp; Location.X &#43;= (int)(Velocity.X * (float)elapsedTime);<br>
&nbsp; &nbsp; Location.Y &#43;= (int)(Velocity.Y * (float)elapsedTime);<br>
} </div>
</li></ul>
<p>So you should now have a project that compiles. However when it runs you will see a runtime error about a missing sound file - copy the WAV file from the original project and add it to the project and set the properties to copy the file to the output directory.
 Now the project should compile and run but nothing will appear on the screen. This is to be expected since the previous version used windows forms to do the rendering.</p>
<h1>Using XNA to Render</h1>
<p>The simplest way to draw anything in XNA is using the SpriteBatch class. This uses your graphics card to draw 2d rectangular areas on the screen. Since Tiny Tennis uses rectangles this is perfect. The
<span>SpriteBatch </span>allows you to set the location and size of the rectangle - however it expects a graphic file to be used as the thing to draw. For TinyTennis a graphic file which is all white will work perfectly. I created a small graphic file using
 Windows Paint and added it to the project.</p>
<p>If you look at the file properties after you add the bitmap you will see another addition that XNA Game Studio Express adds. Image files are now a recognized project item. This is what you may have heard of as the content pipeline. It allows game content
 to be created and checked at compile time and the content to be treated as part of the game rather than some external files.</p>
<p><img height="209" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1256876/tennis4.png" width="278"> &nbsp;</p>
<p>For the most part you don't need to change or even look at the properties window. Make a note of the Asset name - this is how you will be able to refer to it in code. It defaults to the name of the file without the type extension.</p>
<p>Rendering involves 2 steps - loading the graphic and then using it to draw.</p>
<p>Loading the graphic is done in the Game1.cs class. Using the already declared reference to the content
<span>pipeline </span>it requires a simple declaration:</p>
<div class="code">public static Texture2D SpriteTexture; </div>
<p>&nbsp; and a single line of code in the LoadGraphicsContent function:</p>
<div class="code">protected override void LoadGraphicsContent(bool loadAllContent)<br>
{<br>
&nbsp; &nbsp; if (loadAllContent)<br>
&nbsp; &nbsp; {<br>
&nbsp; &nbsp; &nbsp; &nbsp; spriteTexture = content.Load&lt;Texture2D&gt;(&quot;whitePixel&quot;);<br>
&nbsp; &nbsp; }<br>
} </div>
<p>To draw the sprite you need a sprite batch object for this simple application its easiest to just create a single SpriteBatch and make it static so that the bats and balls can share it.
</p>
<div class="code">public static SpriteBatch SpriteBatch; </div>
<p>And create it in the initialize function.</p>
<div class="code">SpriteBatch = new SpriteBatch(this.graphics.GraphicsDevice); </div>
<p>Drawing with SpriteBatch has many overloads - however to draw a rectangle uses the simplest overload which simple stretches the white pixel to a rectangle of the required size and color in sprite.cs</p>
<div class="code">public virtual void Draw()<br>
{<br>
&nbsp; &nbsp; Game1.SpriteBatch.Begin();<br>
&nbsp; &nbsp; Game1.SpriteBatch.Draw(Game1.SpriteTexture, new Rectangle((int)(Location.X &#43; .5f), (int)(Location.Y &#43;.5f), (int)Size.X, (int)Size.Y), Color.White);<br>
&nbsp; &nbsp; Game1.SpriteBatch.End();<br>
} </div>
<p>Now if you run the game you will see the bats and balls on the screen. The final thing is to add the new keyboard code. Since there is no events in XNA you need to simply check each time around the game loop if the key is up or down, Just like everything
 else in XNA this is a few simple lines of code. Replace the humanMove() function in bat.cs with the following:</p>
<p>private void humanMove() <br>
{&nbsp;&nbsp;&nbsp;&nbsp; </p>
<blockquote>
<p>KeyboardState keyState = Keyboard.GetState(); <br>
double velocity = 0.0; &nbsp; &nbsp; <br>
//Set the velocity of the sprite based on which keys are pressed &nbsp; &nbsp; <br>
if (keyState.IsKeyDown(_upKey)) &nbsp; &nbsp; <br>
{ &nbsp; &nbsp; &nbsp; &nbsp; velocity &#43;= -_speed; &nbsp; &nbsp; } &nbsp; &nbsp;<br>
<br>
if (keyState.IsKeyDown(_downKey)) &nbsp; &nbsp; <br>
{ &nbsp; &nbsp; &nbsp; &nbsp; velocity &#43;= _speed; &nbsp; &nbsp; } &nbsp; <br>
&nbsp; <br>
Velocity.Y = (int)velocity; </p>
</blockquote>
<p>} </p>
<h1></h1>
<p><img height="316" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1256876/tennis4.png" width="403">
</p>
<p>Now you can play the game. The keys Q and A control the bat on the left and the bat on the right uses some rudimentary AI.</p>
<h1>Running on the Xbox</h1>
<p>As I mentioned earlier running on the Xbox is something I will cover in the next article. But I'm sure you want to try so here are some pointers:</p>
<ul>
<li>There is no keyboard on the xbox so you will need to <span>replace </span>the key press code with reading the xbox controller instead
</li><li>Sound on the xbox is done using XACT so the SoundPlayer class is not available. You need to create an XACT project and add the .wav file to that
</li></ul>
<p>Take a look at the SpaceWar sample for examples of ow to do both of these things - or just wait till next week.</p>
<p>&nbsp;</p>
<p>The code in this article uses <a href="http://msdn.microsoft.com/vstudio/express/visualCsharp/default.aspx">
Visual C#&nbsp;2005 Express Edition</a> and the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=1C8DC451-2DBE-4ECC-8C57-C52EEA50C20A">
October 2005 DirectX SDK</a></p>
<p>The ZMan is here to solve your XNA Game Studio Express and Managed DirectX programming problems. If you have a question for the ZMan then send it to
<a href="mailto:zman@thezbuffer.com">zman@thezbuffer.com</a>.</p>
<p><b>Credits:</b></p>
<p>Thanks to </p>
<ul>
<li><a href="mailto:web@carlosag.net">Carlos Aguilar</a> for the <a href="http://www.carlosag.net/Tools/CodeColorizer/Default.aspx">
code colorizer</a> </li></ul>
<p>Copyright © 2006 TheZBuffer.com</p>
<p>The ZMan runs the #1 Managed DirectX community website <a href="http://www.thezbuffer.com/">
http://www.thezbuffer.com</a>. </p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:db5142556b8b45c5a06c9e7600d73ea4">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-1-Building-Tiny-Tennis</comments>
      <itunes:summary>



In this article, the ZMan walks through creating Tiny Tennis, a Pong clone, using the XNA Framework



The ZMan
TheZbuffer.com

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual C# Express
, XNA Game Studio Express
Hardware: 
Download: Download








December 11th... a day that we all hope will go down in history as the start of a new generation of hobbyist game developers. Today
XNA Game Studio Express launches. It&#39;s not the first platform to allow home developers access to console development but its is the first one to be fully sanctioned and supported and running on a retail console.
 
So where do you start? XNA Game Studio Express is going to interest people who have no game development experience at all so starting with some simple games is a good idea. You may have seen the 3 games I did for MSDN for their Upgrade Your Game promotion
 - 
Tiny Tennis, 
Space Blitz and 
Crusader. For this series of articles I will walk you through simple XNA applications using as much code from these starter kits as possible. The original tutorials and screencasts will walk you through the game logic and these articles will add in the
 XNA know how. 
Firstly a couple of points: 

Even The ZMan didn&#39;t have access to the retail XBox 360 release before today so for the first part I will only cover the PC. Watch for part 2 to add in the things needed to run on the 360 and go into more detail.
XNA only supports Visual C# Express so although the original games were in Visual Basic, this series will be only in C#
You need to ensure you have 
C# Express and XNA Game Studio Express installed. If you have problems installing or running then ask in the
XNA Game Studio Express Forum.

Making a new XNA game
Installing XNA Game Studio Express adds several new project types to C# Express: 

 
The SpaceWar projects are complete games for the xbox and the windows platforms - they have all the source code, graphics and sound and

Microsoft absolutely want you to use th</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-1-Building-Tiny-Tennis</link>
      <pubDate>Mon, 11 Dec 2006 04:27:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-1-Building-Tiny-Tennis</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1256876_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1256876_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Andy Dunn</dc:creator>
      <itunes:author>Andy Dunn</itunes:author>
      <slash:comments>15</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Intro-to-XNA-Part-1-Building-Tiny-Tennis/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Pac-Man for the Smartphone</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">The article expains writing a game, Pac-Man for Windows Mobile 5.0 Smartphone platform</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Bryan Dougherty</div>
<div class="entry_company"><a href="http://blogs.claritycon.com/blogs/bryan_dougherty">Bryan Dougherty's Blog</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
3-6 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">$50-$100</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"><a href="http://direct.motorola.com/ENS/Web_ProductHome.asp?country=USA&amp;language=ENS&amp;productid=29303">Motorola MPX220</a></span></div>
<div class="entry_details"><b>Download: </b><a href="http://employees.claritycon.com/bdougherty/blog/code/MobilePacMan/build/">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<h2>Introduction</h2>
<p>I've always loved mobile technology and I wanted to try my hand at mobile development. So a little ways back I bought a Smartphone, the
<a href="http://direct.motorola.com/ENS/Web_ProductHome.asp?country=USA&amp;language=ENS&amp;productid=29303">
Motorola MPX220</a>, which runs the Windows Mobile 2003 OS. I hope to upgrade to a new Smartphone soon, so this article will discuss building an application targeting the Windows Mobile 5.0 Smartphone platform.
</p>
<p>When deciding what to do, I thought of a variety of useful applications I could build. Then I decided that making a game would be more fun. I settled on a classic: Pac-Man.</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1044050/pacman_1.png" border="0"></p>
<p><b>Figure 1: Pac-Man running on Windows Mobile 5.0 Smartphone Emulator</b></p>
<h2>Getting Started</h2>
<p>Before diving into code, I thought I'd mention some of the pieces involved in developing for the Smartphone.</p>
<h3>Development Environment</h3>
<p>In order to create applications for the Windows Mobile 5.0 Smartphone platform, the following applications need to be installed:
</p>
<ul>
<li>Visual Studio .NET 2005 Professional Edition<br>
<br>
</li><li>Windows Mobile 5.0 Smartphone SDK<br>
<br>
</li><li>ActiveSync Version 4.1.0 </li></ul>
<h3>New Project</h3>
<p>Once the development environment is set up, the new Mobile 5.0 Smartphone templates appear under the New Project dialog in Visual Studio.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1044050/pacman_2.png" target="_Top"><img alt="Click here for larger image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1044050/pacman_2_thumb.png" border="0"></a></p>
<p><b>Figure 2: New Project dialog in Visual Studio (click image to zoom)</b></p>
<p>Note that you choose which version of the Compact Framework you are targeting when you select the project template. Those targeting CF1.0 have 1.0 after the name, while the others target the 2.0 Framework.
</p>
<p>Development, in general, feels just like development of any WinForm application. You do need to keep in mind, however, that some functionality supported by the standard .NET Framework is not supported by the Compact Framework. For more on support for classes
 you can look <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_evtuv/html/etconnetcompactframeworkclasses.asp">
in the MSDN Library</a>.</p>
<h3>The Emulator</h3>
<p>While developing, you don't have to deploy your application to an actual phone when you want to test. Instead, a built-in emulator, as seen in the Figure 1, is available. With the click of a button, you can deploy to the emulator and test your application
 with full debugging capability, just like you would a WinForm application. The behavior and speed of the emulator seemed to provide a reasonable indication of how the application would perform on an actual phone.</p>
<h2>Development</h2>
<p>Instead of rushing in and trying to crank out the code for Pac-Man, I took a more structured approach. With a few proof of concepts under my belt, I decided to build a framework that would provide the common building blocks needed to create 2-D games for
 a Smartphone. I tried to focus on the following functionality as goals: </p>
<ul>
<li>A game board that controls efficient painting and game flow<br>
<br>
</li><li>A basis for defining game characters supported by the game board<br>
<br>
</li><li>Built-in support for common interactions between characters </li></ul>
<p>A basic litmus test for success would be whether someone (like you) could use this framework to build a classic 2-D video game, like Frogger, by only writing the new code managing interactions between the characters specific to the game.</p>
<p>The remainder of the article will highlight a few of the key concepts I built into the framework.
</p>
<h3>Sprites</h3>
<p>The Sprite class provides the basis for all characters in the game. In Pac-Man, this includes ghosts, dots, walls, and Pac-Man himself. The class is abstract, forcing all derived classes to implement&nbsp;two methods:</p>
<pre><code>public abstract void Update();
public abstract void Draw(Graphics gameSurface);</code></pre>
<p>Not surprisingly, they expect the derived class to update their state and draw themselves to the game board, respectively. Methods are provided for getting the instance of the GameBoard the Sprite has been added to, and detecting collisions between one Sprite
 and a list of other Sprites. In addition,&nbsp;a Sprite instance is expected to manage several state properties:
</p>
<ul>
<li>ID—must be unique per GameBoard <br>
<br>
</li><li>Bounds—a rectangle that defines the perimeter of the object. A future version could use a Region or other construct to more accurately track the area taken up by the Sprite. This property is used for collision detection and drawing.
<br>
<br>
</li><li>Invalid—a boolean that tells the GameBoard whether a Sprite needs to be redrawn
<br>
<br>
</li><li>Visible—a boolean that determines whether a Sprite should be drawn or not </li></ul>
<pre></pre>
<h3>GameBoard</h3>
<p>The GameBoard class controls the flow of the game. It derives from System.Windows.Forms.Form, and like the Sprite class, it is not creatable. This inheritance structure allows the developer to handle any Form events needed&nbsp;for his game. Below is an example
 in which the Pac-Man application's GameBoard class listens to user input by overriding the OnKeyDown method.</p>
<pre><code>protected override void OnKeyDown(KeyEventArgs e)
{
    _KeyPressed = true;
    base.OnKeyDown (e);
    if(e.KeyCode == Keys.Right || e.KeyCode == Keys.Left || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
    {
        switch(e.KeyCode)
        {
            case Keys.Right:
            {
                _Pacman.MovementDirection = MovementDirections.Right;
                break;
            }
            case Keys.Left:
            {
                _Pacman.MovementDirection = MovementDirections.Left;
                break;
            }
            case Keys.Down:
            {
                _Pacman.MovementDirection = MovementDirections.Down;
                break;
            }
            case Keys.Up:
            {
                _Pacman.MovementDirection = MovementDirections.Up;
                break;
            }
        }
    }
}
</code></pre>
<p>Each game application needs to create its own game board class that derives from GameBoard. All character Sprites should then be created and added to the GameBoard's list of Sprites. Then, after the GameBoard loads, a Timer is used to call the Update and
 Draw methods on Sprites as mentioned above.</p>
<h3>Painting</h3>
<p>So how exactly does the drawing of the Sprites work? From a Sprite's perspective, it's simple. All a Sprite needs to know is how to draw itself. A Dot Sprite for example, simply draws a rectangle to the game board graphics object.</p>
<pre><code>public override void Draw(Graphics gameBoard)
{
    if(!_IsEaten)
    {
        gameBoard.FillRectangle(new SolidBrush(Color.LightBlue), _Bounds);
    }
}

</code></pre>
<p>The Draw methods for Pac-Man and Ghost Sprites are more complicated and draw one of a series of bitmap images to the game board. The changing images, along with updated Bounds create animation. When drawn, a color is chosen (magenta in the Figure 3 below)
 to indicate portions of the image that should be treated as transparent.</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1044050/pacman_3.png" border="0"></p>
<p><b>Figure 3: Ghost Sprite image enlarged</b></p>
<p>The GameBoard class makes the screen painting as efficient as possible. It overrides the Form OnPaint and OnPaintBackground methods since it controls all the updating of the screen. The OnPaint method makes sure that only the portions of the screen that
 have changed get repainted. In addition, it uses a back buffer to minimize any flicker.</p>
<pre><code>protected override void OnPaint(PaintEventArgs e)
{
    if(_BackBuffer == null) 
    { 
        return;
    }

    Graphics g = Graphics.FromImage(_BackBuffer);

    ArrayList changedSprites = new ArrayList();
    // blank out any invalid Sprites previous position in the back buffer
    foreach(Sprite sprite in _SpritesByZIndex)
    {
        if(sprite.Invalid)
        {
            g.FillRectangle(new SolidBrush(_BackgroundColor), sprite.PreviousBounds);
            changedSprites.Add(sprite);
        }
    }

    // now draw them to the back buffer
    foreach(Sprite sprite in changedSprites)
    {
        if(sprite.Visible)
        {
            sprite.Draw(g);
        }
    }

    if(_FullRepaint)
    {
        // draw the entire back buffer 
        e.Graphics.DrawImage(_BackBuffer, 0, 0);
        _FullRepaint = false;

        foreach(Sprite sprite in _SpritesByZIndex)
        {
            // reset Invalid flag
            sprite.Invalid = false;
        }
    }
    else
    {
        // only draw the parts that have changed
        foreach(Sprite sprite in changedSprites)
        {
            e.Graphics.DrawImage(_BackBuffer, sprite.Bounds, sprite.Bounds, GraphicsUnit.Pixel);
            e.Graphics.DrawImage(_BackBuffer, sprite.PreviousBounds, sprite.PreviousBounds, GraphicsUnit.Pixel);

            // reset Invalid flag
            sprite.Invalid = false;
        }
    }
}
</code></pre>
<h3>Mobile Development Considerations</h3>
<p>As I've said, from a coding perspective, developing mobile applications in .NET is very similar to building standard WinForm apps. However, this little project did bring to light a number of things you have to keep in mind with mobile applications, most
 centering around the word &quot;small&quot;. </p>
<p>The most obvious consideration is that the device has a small screen. That means you have to design a user interface that is easy to use within the minimal real estate. That tends to translate into keeping things simple. One other screen consideration is
 that from phone to phone, screen size and resolution may change. I didn't address that with my first cut of Pac-Man, but it's on the list. In my testing I targeted a lower resolution that would work on my phone.</p>
<p>With any type of application, but especially with a game, you have to think about how a user will interact with the small keys of his phone, possibly using no more that a thumb! I consciously made controlling Pac-Man a little different than the typical arcade
 feel to make up for some of the clumsiness of using the phone's directional pad. That change has received mixed reviews from the people who have tried it out. That's what testing is for, though, right?</p>
<p>The other &quot;small&quot; consideration is the phone's horsepower. While a Smartphone blows away my old Tandy 64K Color Computer, the computer I started playing games on, I definitely found myself needing to tweak the code for performance. I was sure ahead of time
 that highly efficient painting logic would be necessary. I was surprised, however, to find that the code that prepares the possible travel paths for ghosts takes a considerable amount of time to crunch. For that reason, I made sure that this logic is only
 processed the first time the splash screen is displayed. It is then cached for later reuse.</p>
<h2>Conclusion</h2>
<p>So there it is...well, the first version, at least. I plan to periodically update the game making it more efficient and more fun—smarter ghosts for starters. Maybe I'll even eat my own dog food and try building Frogger to see if that little framework I put
 together holds water. I really want to add a feature to report high scores to a web site. What's a game with out a little healthy competition, right?
</p>
<p>I recently started a <a href="http://blogs.claritycon.com/blogs/bryan_dougherty/default.aspx">
blog</a> about this and other topics related to software development on <a href="http://blogs.claritycon.com/">
my company's blog site</a>. The <a href="http://employees.claritycon.com/bdougherty/blog/code/MobilePacMan/source/">
code</a> and <a href="http://employees.claritycon.com/bdougherty/blog/code/MobilePacMan/build/">
compiled game</a> for the all platforms will be available there, too. Feel free to check for updates and post any feedback you may have.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:47256638bf7c40ebb1d19e7600d8d714">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Pac-Man-for-the-Smartphone</comments>
      <itunes:summary>



&amp;nbsp;
The article expains writing a game, Pac-Man for Windows Mobile 5.0 Smartphone platform



Bryan Dougherty
Bryan Dougherty&#39;s Blog

Difficulty: Intermediate
Time Required: 
3-6 hours
Cost: $50-$100
Software: Visual Basic or Visual C# Express Editions
Hardware: Motorola MPX220
Download: Download








Introduction
I&#39;ve always loved mobile technology and I wanted to try my hand at mobile development. So a little ways back I bought a Smartphone, the

Motorola MPX220, which runs the Windows Mobile 2003 OS. I hope to upgrade to a new Smartphone soon, so this article will discuss building an application targeting the Windows Mobile 5.0 Smartphone platform.
 
When deciding what to do, I thought of a variety of useful applications I could build. Then I decided that making a game would be more fun. I settled on a classic: Pac-Man. 
 
Figure 1: Pac-Man running on Windows Mobile 5.0 Smartphone Emulator 
Getting Started
Before diving into code, I thought I&#39;d mention some of the pieces involved in developing for the Smartphone. 
Development Environment
In order to create applications for the Windows Mobile 5.0 Smartphone platform, the following applications need to be installed:
 

Visual Studio .NET 2005 Professional Edition

Windows Mobile 5.0 Smartphone SDK

ActiveSync Version 4.1.0 
New Project
Once the development environment is set up, the new Mobile 5.0 Smartphone templates appear under the New Project dialog in Visual Studio.
 
 
Figure 2: New Project dialog in Visual Studio (click image to zoom) 
Note that you choose which version of the Compact Framework you are targeting when you select the project template. Those targeting CF1.0 have 1.0 after the name, while the others target the 2.0 Framework.
 
Development, in general, feels just like development of any WinForm application. You do need to keep in mind, however, that some functionality supported by the standard .NET Framework is not supported by the Compact Framework. For more on support for classes
 you</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Pac-Man-for-the-Smartphone</link>
      <pubDate>Thu, 09 Nov 2006 11:06:04 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Pac-Man-for-the-Smartphone</guid>      
      <dc:creator>Bryan Dougherty</dc:creator>
      <itunes:author>Bryan Dougherty</itunes:author>
      <slash:comments>8</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Pac-Man-for-the-Smartphone/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Beginning Game Development: Part VIII - DirectSound</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">In this article, we are going to look at another facet of DirectX, the ability to control sound devices.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Derek Pierson</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b></div>
<div class="entry_details">
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999786/BattleTankPt8_CS.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999786/BattleTankPt8_VB.msi">VB Download</a></li></ul>
</div>
<div class="entry_details"><strong>Beginning Game Development Series</strong></div>
<ol>
<li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx">Beginning Game Development Part 1 - Introduction</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940223.aspx">Beginning Game Development Part II - Introduction to DirectX</a></div>
</li><li>
<div class="entry_details"><a class="" title="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx " href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx">Beginning Game Development: Part III - DirectX II</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940908.aspx">Beginning Game Development: Part IV - DirectInput</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx">Beginning Game Development: Part V - Adding Units</a>
</div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044115.aspx">Beginning Game Development: Part VI - Lights, Materials and Terrain</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044454.aspx">Beginning Game Development: Part VII –Terrain and Collision Detection</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx">Beginning Game Development: Part VIII - DirectSound</a></div>
</li><li>
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2007/11/02/5849691.aspx">Beginning Game Development: Part VIII - DirectSound II</a></div>
</div>
</li><li>
<div class="entry_details">
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7020067.aspx">Beginning Game Development: Part VIII - DirectSound III</a></div>
</div>
</div>
</li></ol>
<a class="" href="http://msdn.microsoft.com/coding4fun/gaming/arcade/article.aspx?articleid=999786&amp;title=Beginning&#43;Game&#43;Development%3a&#43;Part&#43;VIII&#43;-&#43;DirectSound"></a></td>
</tr>
</tbody>
</table>
</span>
<p>Welcome to the eighth article on beginning game development. We have spent a lot of time working with the graphics capabilities of DirectX. We also covered how the DirectX API allows us to control input devices. Now we are going to look at another facet
 of DirectX, the ability to control sound devices. This capability is found in the DirectSound and AudioVideoPlayback namespaces.</p>
<h2>Sound in Games </h2>
<p>Sound creates an ambiance in a game that provides for a more immersive game experience. Imagine how dull a game would be without sound effects; nothing would indicate when you fire your cannon or an explosion occurs. Sounds also can be used to increase the
 drama of a scene by increasing the tempo as the action increases. </p>
<p>Sound effects also provide the same audible cues we expect in real life, such as the direction and speed of a person approaching us based on the volume, direction, and frequency of the footsteps. These sound effects add realism to the game just like proper
 physical behavior of objects do (something I will cover in an upcoming article about physics). Games also provide background music to make playing the game more fun. In newer games, artists who have their music included in a sound track for a popular game
 see an upswing of sales — it is not unusual for well-known artists to provide music for a game soundtrack. In effect, games have reached the same level as movies with the regards to the importance of soundtracks.</p>
<p>In BattleTank2005 I want to integrate sound in the following way. First, I want standard sound effects for shooting, explosions, and engine noise, and I want that sound to be directionally accurate. What I mean is that when I am getting shot at by an enemy
 to my left, I want the sound to come from the left and the volume to be an indicator of the proximity of the unit.</p>
<p>Secondly, I want to be able to play background music during game play and I want to control what music plays when in the game. This means I want to have one song play during the splash screen and game setup, another while playing the game, and yet another
 during the HiScore capturing (we are going to add these screens and states in a later article).</p>
<p>I am going to cover the first requirement in this article, and then cover sound effects and playing MP3 and WMA files with the AudioVideo namespace in the next article. Before we add these features, let's review the capabilities of DirectSound.</p>
<h2>DirectSound</h2>
<p>The DirectSound namespace only supports playing 2 channel waveform audio data at fixed sampling rates (PCM). While I have no idea what that really means, it is safe to state that you should use DirectSound to play short WAV files and the AudioVideoPlayback
 namespace for longer MP3 or WMA files. I am not going to cover how to use the sound capturing/recording capabilities of DirectSound namespace — but remember that they exist so you know where to look if your game requires recording sounds as well as playing
 them.</p>
<p>The DirectSound namespace provides the ability to play and capture sound with three-dimensional positioning effects. DirectSound also provides the ability to add sound effects to the audio played or recorded. Just like in the DirectX3D and the DirectInput
 namespaces, the actual hardware device used is abstracted into a device class. Just like the device classes in those two namespaces, the DirectSound device uses buffers, has a cooperative level, and has device capabilities. I am not going to cover the sound
 effects in this article, but they are not forgotten; they will be covered in detail in the next article.</p>
<h3>Device</h3>
<p>A device is the interface to the audio hardware on the computer. You can either create a Device class using a default GUID (DSoundHelper.DefaultPlaybackDevice) or enumerate all the devices on a system. Like the other device classes, each enumerated device
 has a list of capabilities stored in a Caps structure in the <b>Caps</b> property for the device. Once you have chosen your device, you instantiate the device class using a specific GUID.</p>
<p>Audio devices also have a cooperative level like the input devices did. The three possible values are: Normal, Priority, and Write Primary. These values are set via the CooperativeLevel enumeration.</p>
<table class="" cols="cols" rules="all" width="504" border="1" frame="box">
<tbody>
<tr valign="top">
<td class="" width="148"><b>Cooperative Level</b></td>
<td class="" width="354"><b>Meaning</b></td>
</tr>
<tr valign="top">
<td class="" width="150">Normal</td>
<td class="" width="354">The application cannot set the format of, or write to, the primary buffer. For all the applications that use this level, the primary buffer setting is locked at 22 kHz, stereo, 8-bit samples.</td>
</tr>
<tr valign="top">
<td class="" width="150">Priority</td>
<td class="" width="354">Provides first rights to access hardware resources for mixing, etc., and can change the format of the primary sound buffer.
<i>This is the preferred setting for games</i>.</td>
</tr>
<tr valign="top">
<td class="" width="150">Write Primary</td>
<td class="" width="354">Provides direct access to the primary sound buffer, but the application must write directly to the primary buffer.</td>
</tr>
</tbody>
</table>
<br>
<h3>Buffers</h3>
<p>All the sounds in DirectX are controlled via buffers. These buffers can exist in the memory of the computer or on the sound card itself. The two buffers used in DirectSound are called the primary buffer and secondary buffer.
</p>
<p>The <b>primary buffer</b> contains the actual audio data that is sent to the device and is automatically created and managed by the DirectX API. The API mixes the sound in the primary buffer with any secondary buffers. If you need to interact directly with
 the primary buffer, make sure to change the Cooperative level of the device to Write Primary.</p>
<p><b>Secondary buffers</b> hold a single audio stream and must be explicitly created by the application. Each application must create at least one secondary buffer to store and play sounds. Each secondary buffer also has a specific waveform format (described
 in the WaveFormat structure), and only sound data that matches that format can be loaded into that secondary buffer. An application can play sounds of differing formats by creating a separate secondary buffer for each format and letting the API mix them into
 a common format in the primary buffer. To mix sounds in two different secondary buffers, simply play them at the same time and let the API mix them in the primary buffer. The only limitation to the number of different secondary buffers that can be mixed is
 the processing power of the system, but remember that any additional processing required will also slow down your game. We have not added any AI or physics computations, but we should be careful with the available processing power.</p>
<p>Any secondary buffer can be used for the life of the application, or it can be created and destroyed as needed. A single secondary buffer can contain the same data throughout the entire game or it can be loaded with different sounds (as long as they match
 the format). The sound in the secondary buffer can be played once or set up to loop. If the sound to be played is short, it can be loaded into the buffer in its entirety (called a static buffer), but longer sounds must be streamed. It is the responsibility
 of the application to manage the streaming of the sound to the buffer. </p>
<p>When a buffer is created you have to specify the control options for that buffer using the BufferDescription class. If you use a property of the buffer without first setting it in the control properties, an exception is thrown. The control options can be
 combined by either setting each property to true or combined in the <b>Flag</b> property.</p>
<div>
<div>
<pre><span> 1:</span> BufferDescription bufferDescription = <span>new</span> BufferDescription ( );</pre>
<pre><span> 2:</span> <span>// Use the seperate properties</span></pre>
<pre><span> 3:</span> bufferDescription.ControlVolume = <span>true</span>;</pre>
<pre><span> 4:</span> bufferDescription.ControlPan = <span>true</span>;</pre>
<pre><span> 5:</span> <span>// or combine them in the Flags property</span></pre>
<pre><span> 6:</span> bufferDescription.Flags = BufferDescriptionFlags.ControlVolume | BufferDescriptionFlags.ControlPan;</pre>
</div>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h3>Controlling Volume, Pan, and Frequency</h3>
<p>To control these settings of the buffer you must first set the <b>ControlPan, ControlVolume</b>, and
<b>ControlFrequency</b> properties of the buffer to true. You can then set the pan, volume, and frequency values using the buffer's Pan, Volume, and Frequency properties.</p>
<p><b>Volume</b> is expressed in hundredths of a decibel and ranges from 0 (full volume) to -10,000 (completely silent). The decibel scale is not linear, so you may reach effective silence well before the volume setting reaches true silence at -10,000. There
 is also no way to increase the volume of the sound above the volume it was recorded at, so you have to make sure to record the sound with a high enough volume to at least match the desired maximum volume in the game.</p>
<p><b>Pan</b> is expressed as an integer and ranges from -10,000 (full left) to &#43;10,000 (full right), with 0 being center.
</p>
<p>The <b>frequency</b> value is expressed in samples per seconds and represents the playback speed of the buffer. A larger number plays the sound faster and raises the pitch while a smaller number slows the speed down and lowers the pitch. To reset the sound
 to its original frequency, simply set the frequency value to 0. The minimum value for frequency is 100 and the maximum value is 200,000.</p>
<p>At this point you may think that we could use the volume, pan, and frequency settings to manipulate the sound and make it reflect the direction and distance of its origin. This was, after all, one of our original requirements. But instead of us performing
 the calculations to determine the relative locations and distances of each object, DirectX provides an API to do just that for us.
</p>
<h2>3D Sound</h2>
<p>The 3D features of DirectX allow us to locate sounds in space and apply Doppler shift to moving sounds.</p>
<p><b>Note</b>&nbsp;&nbsp; Check out this excellent <a href="http://en.wikipedia.org/wiki/Doppler_effect">
explanation of the Doppler effect</a> at Wikipedia, or use this <a href="http://www.lon-capa.org/~mmp/applist/doppler/d.htm">
applet</a> to help yourself to visualize what it is.</p>
<p>Before describing how DirectX handles sound in three dimensions, it is probably useful to talk about how we perceive sound. DirectX uses these same principles to make the sound appear as realistic as possible.
</p>
<ol>
<li>The volume of a sound decreases at a fixed rate as the distance to the listener increases. This effect is called Rolloff. The relationship between the volume of a sound and its distance from the listener is inverse-proportional, meaning that if the distance
 is halved the volume doubles. (See: <a href="http://en.wikipedia.org/wiki/Inverse_square_law">
http://en.wikipedia.org/wiki/Inverse_square_law</a>) <br>
<br>
</li><li>The listener perceives sounds coming from the left as louder in the left ear than the in right ear (interaural intensity difference) and also hears sounds coming from the left sooner in the left ear than the right ear (interaural time difference). (See:
<a href="http://en.wikipedia.org/wiki/Interaural_Intensity_Difference">http://en.wikipedia.org/wiki/Interaural_Intensity_Difference</a>)
<br>
<br>
</li><li>The shape of the ear produces an effect called &quot;muffling&quot;: sounds coming from the front are perceived as louder than those coming from the back. This is, of course, because the human ear is directed towards the front of the head.
<br>
<br>
</li><li>The ridges of the earlobe slightly alter the sound arriving from different directions. This provides cues to the brain about the location of the sound source. This effect can be modeled mathematically and is called the Head Related Transfer Function (HRTF).
 (See: <a href="http://en.wikipedia.org/wiki/Head_Related_Transfer_Function">http://en.wikipedia.org/wiki/Head_Related_Transfer_Function</a>)</li></ol>
<p>We already know that DirectX uses the left-handed Cartesian coordinates system and Vectors to express position and directional information. This same system is also used by DirectSound in its computations. One important piece of information when dealing
 with 3D sound is that the default unit of measurement for distance is the meter and the default measurement for velocity is meters per second. You need to make sure to use a common system of measurement in the game. You can change this by setting the
<b>DistanceFactor</b> property of the Listener3D object to a value that represents the meters per application-specified distance unit. If you have been using feet in all your calculations up to this point, simply set this value to 0.3048 (there are 0.3048 meters
 in a foot). </p>
<p>Also, since we are leaving the manipulation of the sound to DirectX (as opposed to us changing the volume, pan, and frequency), we must ensure that the sound source we are using is a mono and not stereo source. Finally, make sure to set the
<b>Control3D</b> property of the buffer to true to enable 3D sounds. </p>
<p>DirectSound uses two objects to manage 3D sounds in the application: <b>Buffer3D</b> and
<b>Listener3D</b>.</p>
<h3>3D Buffers</h3>
<p>Unlike the SecondaryBuffer, a Buffer3D object does not inherit from the Buffer class. Instead you create a 3D Buffer object by passing it a SecondaryBuffer in the constructor. The 3D Buffer exposes a number of properties that determine how the sound is processed.</p>
<p>The <b>MinDistance</b> property determines at which distance the sound volume is no longer increased. You can also use this setting to make certain sounds appear louder even if they were recorded at the same volume (see the DirectX documentation for a detailed
 explanation of this). The default value for this property is 1 meter, meaning that the sound is at full volume when the distance between the listener and the sound source equals 1 meter.</p>
<p>The <b>MaxDistance</b> property is the opposite and determines the distance after which the sound no longer decreases in volume. The default value for this property is 1 billion meters, which is well beyond hearing range anyway. To avoid unnecessary processing,
 you should set this value to a reasonable value and set the <b>Mute3DAtMaximumDistance</b> property of the BufferDescription to true.</p>
<p>Finally, we can also specify values for the sound cone if the sound is directional. A sound cone is almost identical to the cone produced by a spotlight (see article 6). It consists of a set of angles, one for the inside and one for the outside cone, and
 orientation, and an outside volume property. Check out the <a href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_m/directx/sound/3-dsound/directsound_3-d_buffers.asp">
DirectX documentation</a> for more detail on sound cones.</p>
<h3>3D Listeners</h3>
<p>While the 3D Buffer describes the source of a sound, the 3D Listener describes the, well, listener. Just as the position, orientation, and velocity of the buffer affects the sound, so does the position, orientation, and velocity of the listener. The default
 listener in DirectX is located at the origin pointing toward the positive z-axis, and the top of the head is along the positive y-axis. Each application can only have one Listener3D object.</p>
<p>To change the way the player hears the sound in your game, you manipulate the position, orientation, and velocity of the Listener. You can also control global settings of the acoustic environment like the Doppler shift or Rolloff factor.
</p>
<p><b>Note</b>&nbsp;&nbsp; The <b>DopplerFactor</b> and <b>RolloffFactor</b> properties are a number between 0 and 10. Zero means that the value is turned off. One represents the real world values of these acoustic effects. All other values are multiples, so that a 2
 means doubling the real world effect, 3 means tripling it, and so on.</p>
<p>In BattleTank2005 we are going to add three new classes; a SoundDevice class to represent the actual audio device, a SoundListner class to encapsulate the Listener3D object, and a SoundEffects class to represent each separate sound effect. Each tank in BattleTank2005
 can have multiple sounds associated with it, such as engine noise and the noise made when firing. To integrate sound we are going to update the Tank class to play these sounds at the appropriate time and with the appropriate position information. I did not
 add this functionality to the UnitBase class because the stationary objects (the obstacles) will not have any sounds associated with them.</p>
<p>Before we start adding these classes we need add a reference to the Microsoft.DirectX.DirectSound.DLL assembly. Make sure to choose the 1.0 and not the 2.0 version. BattleTank2005 has not yet been updated to use the beta versions of the 2.0 DirectX API.
 Add a new class called SoundDevice and add the using statement for Microsoft.DirectX.DirectSound. All three of the classes will implement the IDisposable interface and use the same Dispose pattern that we used in the Keyboard and Mouse classes. (I omitted
 that portion from the code samples below to keep them more compact and easy to understand).</p>
<p>Following the now familiar patterns we add a private variable called _device to the SoundDevice class and instantiate it in the constructor. We also need to set the CooperativeLevel before we can use the device. As discussed earlier, we will use CooperativeLevel.Priority
 setting. We also pass a reference of the game form to this method so that the device can receive Windows messages. Finally, we surround the device creation code with a Try/Catch, since things can go wrong whenever we work with devices.</p>
<pre class="csharpcode"></pre>
<div>
<div>
<pre><span> 1:</span> <span>using</span> System;</pre>
<pre><span> 2:</span> <span>using</span> Microsoft.DirectX.DirectSound;</pre>
<pre><span> 3:</span>&nbsp; </pre>
<pre><span> 4:</span> <span>namespace</span> BattleTank2005</pre>
<pre><span> 5:</span> { </pre>
<pre><span> 6:</span> <span>class</span> SoundDevice : IDisposable </pre>
<pre><span> 7:</span> { </pre>
<pre><span> 8:</span> <span>public</span> SoundDevice( System.Windows.Forms.Form parentForm ) </pre>
<pre><span> 9:</span> { </pre>
<pre><span> 10:</span> <span>try</span></pre>
<pre><span> 11:</span> {</pre>
<pre><span> 12:</span> _device = <span>new</span> Microsoft.DirectX.DirectSound.Device(); _device.SetCooperativeLevel(parentForm, CooperativeLevel.Priority); } <span>catch</span></pre>
<pre><span> 13:</span> {</pre>
<pre><span> 14:</span> <span>// Can not use sounds</span></pre>
<pre><span> 15:</span> }</pre>
<pre><span> 16:</span> }</pre>
<pre><span> 17:</span> </pre>
<pre><span> 18:</span> <span>public</span> Microsoft.DirectX.DirectSound.Device AudioDevice </pre>
<pre><span> 19:</span> { </pre>
<pre><span> 20:</span> get { <span>return</span> _device; } </pre>
<pre><span> 21:</span> } </pre>
<pre><span> 22:</span> </pre>
<pre><span> 23:</span> <span>private</span> Microsoft.DirectX.DirectSound.Device _device; </pre>
<pre><span> 24:</span> }</pre>
<pre><span> 25:</span> }</pre>
</div>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The next class we need is the SoundListener class. After adding the using statements for DirectSound and DirectX, we construct the class by passing a reference to the SoundDevice class created earlier. The Listener needs to be associated with the Primary
 Buffer of the audio card so it can &quot;hear&quot; the final mixed sounds. Even so, the SoundListener class is largely passive, so we do need to update its position, velocity, and orientation to enable 3D sounds on the buffer. Once the buffer is created we pass it
 to the constructor of the Listener3D class to create the Listener. The final step is to store the Listener3DSettings of the listener in a local variable so we can access them in the Update method.</p>
<p>The Update method provides the way in which we pass the position information to the Listener object.</p>
<p>The last step is to apply the updated values to the Listener. We do this by calling the CommitDeferredSettings method of the Listener3D class after updating the Listener3DSettings values. This method simply commits all changes made to the Listener3DSettings
 since the last time the method was called. When all is done, the SoundListener class is positioned at the correct location in the game.</p>
<pre class="csharpcode"></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<div>
<div>
<pre><span> 1:</span> <span>using</span> System;</pre>
<pre><span> 2:</span> <span>using</span> Microsoft.DirectX;</pre>
<pre><span> 3:</span> <span>using</span> Microsoft.DirectX.DirectSound;</pre>
<pre><span> 4:</span>&nbsp; </pre>
<pre><span> 5:</span> <span>namespace</span> BattleTank2005</pre>
<pre><span> 6:</span> { </pre>
<pre><span> 7:</span> <span>class</span> SoundListener : IDisposable </pre>
<pre><span> 8:</span> { </pre>
<pre><span> 9:</span> <span>public</span> SoundListener(SoundDevice soundDevice) </pre>
<pre><span> 10:</span> { </pre>
<pre><span> 11:</span> BufferDescription bufferDescription = <span>new</span> BufferDescription(); </pre>
<pre><span> 12:</span> bufferDescription.PrimaryBuffer = <span>true</span>; </pre>
<pre><span> 13:</span> bufferDescription.Control3D = <span>true</span>; </pre>
<pre><span> 14:</span> </pre>
<pre><span> 15:</span> <span>// Get the primary buffer</span></pre>
<pre><span> 16:</span> Microsoft.DirectX.DirectSound.Buffer buffer = <span>new</span> Microsoft.DirectX.DirectSound.Buffer(bufferDescription, soundDevice.AudioDevice); </pre>
<pre><span> 17:</span>&nbsp; </pre>
<pre><span> 18:</span> <span>// Attach the listener to the primary buffer</span></pre>
<pre><span> 19:</span> _listener3d = <span>new</span> Listener3D(buffer); </pre>
<pre><span> 20:</span> </pre>
<pre><span> 21:</span> <span>// Store the initial parameters</span></pre>
<pre><span> 22:</span> _listenerSettings = <span>new</span> Listener3DSettings(); </pre>
<pre><span> 23:</span> _listenerSettings = _listener3d.AllParameters; </pre>
<pre><span> 24:</span> } </pre>
<pre><span> 25:</span>&nbsp; </pre>
<pre><span> 26:</span> <span>public</span> <span>void</span> Update(Vector3 position ) </pre>
<pre><span> 27:</span> { </pre>
<pre><span> 28:</span> _listener3d.Position = position; </pre>
<pre><span> 29:</span> _listener3d.CommitDeferredSettings(); </pre>
<pre><span> 30:</span> } </pre>
<pre><span> 31:</span> </pre>
<pre><span> 32:</span> <span>private</span> Microsoft.DirectX.DirectSound.Listener3D _listener3d; </pre>
<pre><span> 33:</span> <span>private</span> Listener3DSettings _listenerSettings; </pre>
<pre><span> 34:</span> }</pre>
<pre><span> 35:</span> }</pre>
</div>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now that we have classes representing the audio device and a class to &quot;listen&quot; to the sounds, we need to actually create the sounds. For this we add the SoundEffect class. Once again we need to add the using statement for the DirectSound namespace. We also
 need to add a using statement for the DirectX namespace because we are going to use the Vector3 class.</p>
<p>A SoundEffect is created by passing a reference to the SoundDevice and a path to a WAV file containing a sound. In the constructor, we create a BufferDescription object that will &quot;turn on&quot; all of the capabilities we want. For right now we want the ability
 to control sounds in 3D, adjust the volume, and change the frequency. Next we create a secondary buffer passing in the path to the sound file and the BufferDescription we just created. To create the Buffer3D that we need to play 3D sounds, we pass the SecondaryBuffer
 to the Buffer3D class on instantiation, and voila! we have a 3DBuffer.</p>
<p>Once the Buffer3D class is set up we can access the properties and change the settings. We set the MaxDistance to a more manageable number. This setting combined with the Mute3DAtMaximumDistance setting on the SecondaryBuffer ensures that sounds too distant
 to hear are not played at all and don't consume any processing cycles.</p>
<p>To actually use the SoundEffect in the game we provide three public methods: one to play the sound one to stop the Sound (if it is looping) and one to update the class. The Play method either plays the sound once or loops the sound depending on the setting
 of the _isLooping variable. If the sound is looping, we need to be able to stop it, and that is what the Stop method does. The Update method is the way in which we pass the updated position of the tank the sound is associated with to the sound buffer so it
 can be accurately calculated.</p>
<div>
<div>
<pre><span> 1:</span> <span>using</span> System;</pre>
<pre><span> 2:</span> <span>using</span> Microsoft.DirectX.DirectSound;</pre>
<pre><span> 3:</span> <span>using</span> Microsoft.DirectX;</pre>
<pre><span> 4:</span>&nbsp; </pre>
<pre><span> 5:</span> <span>namespace</span> BattleTank2005</pre>
<pre><span> 6:</span> { </pre>
<pre><span> 7:</span> <span>public</span> <span>class</span> SoundEffects : IDisposable </pre>
<pre><span> 8:</span> { </pre>
<pre><span> 9:</span> <span>public</span> SoundEffects( SoundDevice soundDevice, <span>string</span> soundFile) </pre>
<pre><span> 10:</span> { </pre>
<pre><span> 11:</span> BufferDescription bufferDescription = <span>new</span> BufferDescription(); </pre>
<pre><span> 12:</span> bufferDescription.Control3D = <span>true</span>; </pre>
<pre><span> 13:</span> bufferDescription.ControlVolume = <span>true</span>; </pre>
<pre><span> 14:</span> bufferDescription.ControlFrequency = <span>true</span>; </pre>
<pre><span> 15:</span> bufferDescription.Mute3DAtMaximumDistance = <span>true</span>; </pre>
<pre><span> 16:</span> </pre>
<pre><span> 17:</span> <span>try</span></pre>
<pre><span> 18:</span> {</pre>
<pre><span> 19:</span> _secondaryBuffer = <span>new</span> SecondaryBuffer(soundFile, bufferDescription, soundDevice.AudioDevice); </pre>
<pre><span> 20:</span> _3dBuffer = <span>new</span> Buffer3D(_secondaryBuffer); </pre>
<pre><span> 21:</span> _3dBuffer.MaxDistance = 10000; </pre>
<pre><span> 22:</span> }</pre>
<pre><span> 23:</span> <span>catch</span></pre>
<pre><span> 24:</span> {</pre>
<pre><span> 25:</span> <span>// Can not use sounds</span></pre>
<pre><span> 26:</span> }</pre>
<pre><span> 27:</span> }</pre>
<pre><span> 28:</span> </pre>
<pre><span> 29:</span> <span>public</span> <span>void</span> Update(Vector3 position){ </pre>
<pre><span> 30:</span> _3dBuffer.Position = position; </pre>
<pre><span> 31:</span> } </pre>
<pre><span> 32:</span> </pre>
<pre><span> 33:</span> <span>public</span> <span>void</span> Play() </pre>
<pre><span> 34:</span> { </pre>
<pre><span> 35:</span> <span>if</span> (_isLooping == <span>true</span>) </pre>
<pre><span> 36:</span> _secondaryBuffer.Play(0, BufferPlayFlags.Looping); </pre>
<pre><span> 37:</span> <span>else</span></pre>
<pre><span> 38:</span> _secondaryBuffer.Play(0, BufferPlayFlags.Default);</pre>
<pre><span> 39:</span> }</pre>
<pre><span> 40:</span>&nbsp; </pre>
<pre><span> 41:</span> <span>public</span> <span>void</span> Stop() </pre>
<pre><span> 42:</span> { </pre>
<pre><span> 43:</span> _secondaryBuffer.Stop(); </pre>
<pre><span> 44:</span> _secondaryBuffer.SetCurrentPosition(0); </pre>
<pre><span> 45:</span> } </pre>
<pre><span> 46:</span> </pre>
<pre><span> 47:</span> <span>public</span> <span>bool</span> IsLooping </pre>
<pre><span> 48:</span> { </pre>
<pre><span> 49:</span> set { _isLooping = <span>value</span>; } </pre>
<pre><span> 50:</span> } </pre>
<pre><span> 51:</span>&nbsp; </pre>
<pre><span> 52:</span> <span>public</span> <span>int</span> Volume </pre>
<pre><span> 53:</span> { </pre>
<pre><span> 54:</span> set { _secondaryBuffer.Volume = <span>value</span>; } </pre>
<pre><span> 55:</span> } </pre>
<pre><span> 56:</span>&nbsp; </pre>
<pre><span> 57:</span> <span>public</span> <span>int</span> Frequency </pre>
<pre><span> 58:</span> { </pre>
<pre><span> 59:</span> set { _secondaryBuffer.Frequency = <span>value</span>; } </pre>
<pre><span> 60:</span> } </pre>
<pre><span> 61:</span>&nbsp; </pre>
<pre><span> 62:</span> <span>private</span> SecondaryBuffer _secondaryBuffer; </pre>
<pre><span> 63:</span> <span>private</span> Buffer3D _3dBuffer; </pre>
<pre><span> 64:</span> <span>private</span> <span>bool</span> _isLooping; </pre>
<pre><span> 65:</span> }</pre>
<pre><span> 66:</span> }</pre>
</div>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre class="csharpcode"></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now we need to integrate these new classes into the overall game. The first step is to add a private variable to the GameEngine class to hold a reference to the SoundDevice and SoundListener classes because we can only have one of each of these classes.
 At the bottom of the GameEngine class, add the following code:</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">private</span> SoundDevice _soundDevice;

  <br><span class="kwrd">private</span> SoundListener _soundListener;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next, we need to instantiate each class. The Initialize class of the GameEngine is the perfect spot for this, but to keep sound-related items together we will create a method called ConfigureSounds. In the GameEngine class add the following method:</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ConfigureSounds()

  <br>{

  <br>_soundDevice = <span class="kwrd">new</span> SoundDevice(<span class="kwrd">this</span>);

  <br>_soundListener = <span class="kwrd">new</span> SoundListener(_soundDevice);

  <br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now add a call to the ConfigureSounds method to the Initialize method of the GameEngine right after the call to the ConfigureDevice method.</p>
<pre><code>ConfigureDevice();
    <br>ConfigureSounds()</code></pre>
<p>With regard to the SoundDevice class, this is all we have to do. After creation all we need this class for is its reference to the
<b>Device</b> object. The SoundListener class, however, needs to be updated with the correct position information in each frame. The Render method of the GameEngine class is the perfect place for this. We simply pass in the position of the camera class since
 it represents our location in the game. In the Render method of the GameEngine class, add the following code immediately after the call to the Update method of the camera.</p>
<code>_soundListener.Update(_camera.Position ); <br>
</code>
<p>Each tank gets a unique instance of the SoundEffect class for each sound it can make. First we need to add some private variables to hold the two sound effects we want the tank to make. At the bottom of the Tank class add the following code:</p>
<pre class="csharpcode"><span class="kwrd">private</span> SoundEffects _engineSound;

  <br><span class="kwrd">private</span> SoundEffects _fireSound;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre class="csharpcode"></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>To make sure each tank has the necessary sound we will pass them in the constructor. Update the constructor of the Tank class to look as follows (the new code is in bold):</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<div>
<div>
<pre><span> 1:</span> <span>public</span> Tank(Device device, <span>string</span> meshFile, Vector3 position, <span>float</span> scale, </pre>
<pre><span> 2:</span> <span>float</span> speed, SoundEffects fireSound, SoundEffects engineSound)</pre>
<pre><span> 3:</span> : <span>base</span>(device, meshFile, position, scale)</pre>
<pre><span> 4:</span> { </pre>
<pre><span> 5:</span> _speed = speed; </pre>
<pre><span> 6:</span> _engineSound = engineSound; </pre>
<pre><span> 7:</span> _engineSound.IsLooping = <span>true</span>; </pre>
<pre><span> 8:</span> _engineSound.Play(); </pre>
<pre><span> 9:</span> _fireSound = fireSound; </pre>
<pre><span> 10:</span> }</pre>
</div>
</div>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Once the sound effects are associated with the tank instance we start the engine sound after setting it to looping.
</p>
<p>The next step is to change the Update method of the Tank class to add updating the 3D buffer with the position of the tank. Add the following code to the end of the Update method:</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">if</span> (_engineSound != <span class="kwrd">null</span>)

  <br>{

  <br>_engineSound.Update(<span class="kwrd">base</span>.Position);

  <br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The shooting sound of the tank is not continuous, and whether or not the tank shoots will be determined by the AI we are going to add later on. For now, all we are going to do is create the necessary framework to play the shooting sound. Add the following
 method to the Tank class:</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Shoot()

  <br>{

  <br><span class="kwrd">if</span> (_fireSound != <span class="kwrd">null</span>)

  <br>{

  <br>_fireSound.Update(<span class="kwrd">base</span>.Position);

  <br>_fireSound.Play();

  <br>}

  <br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The final step for updating the tank class to be sound ready is to update the CreateTanks method of the GameEngine. We need to create the SoundEffect for the engine noise and the firing noise, and pass them to the tank class on creation. Change the CreateTanks
 method to look as follows:</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> CreateTanks()

  <br>{

  <br>_tanks = <span class="kwrd">new</span> List&lt;UnitBase&gt;();

  <br>SoundEffects engineSound1 = <span class="kwrd">new</span> SoundEffects(_soundDevice, <span class="str">@&quot;EngineSound1.wav&quot;</span>);

  <br>engineSound1.Volume = -1000;

  <br>engineSound1.Frequency = 100000; <span class="rem">// Set to a value between 100 - 200000</span> SoundEffects engineSound2 = <span class="kwrd">new</span> SoundEffects(_soundDevice, <span class="str">@&quot;EngineSound2.wav&quot;</span>);

  <br>engineSound2.Volume = -1000;

  <br>engineSound2.Frequency = 10000; <span class="rem">// Set to a value between 100 - 200000</span> SoundEffects fireSound = <span class="kwrd">new</span> SoundEffects(_soundDevice, <span class="str">@&quot;Fire.wav&quot;</span>);

  <br>Tank newTank1 = <span class="kwrd">new</span> Tank(_device, <span class="str">@&quot;bigship1.x&quot;</span>, <span class="kwrd">new</span> Vector3(0.0f, 20.0f, 100.0f), 

  <br> 1f, 10.0f, fireSound, engineSound1);

  <br>Tank newTank2 = <span class="kwrd">new</span> Tank(_device, <span class="str">@&quot;bigship1.x&quot;</span>, <span class="kwrd">new</span> Vector3(100.0f, 20.0f, 100.0f), 

  <br> 1f, 10.0f, fireSound, engineSound2);

  <br>_tanks.Add(newTank1);

  <br>_tanks.Add(newTank2);

  <br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This is where you can experiment with changing the volume or frequency of the sound effect. Fly around and get closer to each spaceship, and the sound will vary in direction and volume according to your position. Change the frequency, and the pitch will
 change, and you can guess what the volume setting does.</p>
<h2>Summary</h2>
<p>When you play BattleTank2005 now, you should hear the engine noises of the various enemy tanks properly adjusted for their spatial relationship to the listener (you). At this point, we have integrated the first set of the audio features we want to add to
 BattleTank2005. You should definitely experiment with the various settings to hear their effect. I have left several optional settings commented in the code so you can easily change them. In the next article we are going to cover how to use the built-in sound
 effect manipulation of DirectSound to change the sounds, and how to play a regular MP3 file for the soundtrack using the AudioVideoPlayback namespace.</p>
<p>Until then: Happy coding!</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:bc4c75df1e224a01933a9e7600d92fd5">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-VIII-DirectSound</comments>
      <itunes:summary>



&amp;nbsp;
In this article, we are going to look at another facet of DirectX, the ability to control sound devices.



Derek Pierson
3Leaf Development

Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions
Hardware: 
Download: 


C# Download
VB Download

Beginning Game Development Series


Beginning Game Development Part 1 - Introduction

Beginning Game Development Part II - Introduction to DirectX

Beginning Game Development: Part III - DirectX II

Beginning Game Development: Part IV - DirectInput

Beginning Game Development: Part V - Adding Units


Beginning Game Development: Part VI - Lights, Materials and Terrain

Beginning Game Development: Part VII –Terrain and Collision Detection

Beginning Game Development: Part VIII - DirectSound


Beginning Game Development: Part VIII - DirectSound II




Beginning Game Development: Part VIII - DirectSound III








Welcome to the eighth article on beginning game development. We have spent a lot of time working with the graphics capabilities of DirectX. We also covered how the DirectX API allows us to control input devices. Now we are going to look at another facet
 of DirectX, the ability to control sound devices. This capability is found in the DirectSound and AudioVideoPlayback namespaces. 
Sound in Games 
Sound creates an ambiance in a game that provides for a more immersive game experience. Imagine how dull a game would be without sound effects; nothing would indicate when you fire your cannon or an explosion occurs. Sounds also can be used to increase the
 drama of a scene by increasing the tempo as the action increases.  
Sound effects also provide the same audible cues we expect in real life, such as the direction and speed of a person approaching us based on the volume, direction, and frequency of the footsteps. These sound effects add realism to the game just like proper
 physical behavior of objects do (something I will cover in an upcoming article a</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-VIII-DirectSound</link>
      <pubDate>Mon, 06 Nov 2006 11:26:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-VIII-DirectSound</guid>      
      <dc:creator>Derek Pierson</dc:creator>
      <itunes:author>Derek Pierson</itunes:author>
      <slash:comments>22</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-VIII-DirectSound/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Beginning Game Development: Part V - Adding Units</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This is Part 5 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers adding of 3D objects to the game using predefined mesh files and implementing
 some simple culling.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Derek Pierson</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
3-6 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a>,
<a href="http://www.microsoft.com/windows/directx/default.mspx">DirectX SDK</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">None</span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/941679/BattleTank2005Units-CS.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/941679/BattleTank2005Units-VB.msi">VB Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<div class="entry_details"><strong>Beginning Game Development Series</strong></div>
<ol>
<li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx">Beginning Game Development Part 1 - Introduction</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940223.aspx">Beginning Game Development Part II - Introduction to DirectX</a></div>
</li><li>
<div class="entry_details"><a class="" title="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx " href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx">Beginning Game Development: Part III - DirectX II</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940908.aspx">Beginning Game Development: Part IV - DirectInput</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx">Beginning Game Development: Part V - Adding Units</a>
</div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044115.aspx">Beginning Game Development: Part VI - Lights, Materials and Terrain</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044454.aspx">Beginning Game Development: Part VII –Terrain and Collision Detection</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx">Beginning Game Development: Part VIII - DirectSound</a></div>
</li><li>
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2007/11/02/5849691.aspx">Beginning Game Development: Part VIII - DirectSound II</a></div>
</div>
</li><li>
<div class="entry_details">
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7020067.aspx">Beginning Game Development: Part VIII - DirectSound III</a></div>
</div>
</div>
</li></ol>
<p>Welcome to the fifth article on beginning game development. At this point we have a working 3D environment and can manipulate the camera direction and location using the keyboard and mouse. In this article we are going to add 3D objects to the game using
 predefined mesh files and implement some simple culling.</p>
<h4>Code cleanup</h4>
<p>The cleanup in this article consists mainly of fixing the navigation keys and removing some items we no longer need. The following changes have already been integrated into the code for this article:
</p>
<ul>
<li>Replaced the radian/degree conversion methods in the <b>Camera</b> class with the utility classes in the
<b>Geometry</b> class. </li><li>Fixed the key assignments in the <b>CheckForInput</b> method in the <b>GameEngine</b> class so that:
<ul>
<li>W and S adjust the Z-axis. W is forward (positive) and S backward (negative) </li><li>A and D adjust the X-axis. A is left (negative) and D is right (positive). </li><li>Q and Z adjust the Y-axis. Q is up (positive) and Z is down (negative). Movement along the Y-axis is going to be removed later on, since our tank can not fly.
</li></ul>
</li><li>Adjusted the initial position of the camera to be above the surface level by setting the
<code>_z</code> variable in the Camera class to 10. This represents our vantage point in the tank, which should be higher than zero.
</li><li>Removed the Joystick class. </li><li>Updated to the August SDK. </li><li>Changed the <b>GetElapsedTime</b> method in the <b>HiResTimer</b> class to return a float and changed
<code>_deltaTime</code> in <b>GameEngine</b> to a float. </li><li>Removed <b>HiResTimer.Reset</b> from the <b>GameEngine</b> <b>Render</b> method, moved
<b>HiResTimer.Start</b> into the constructor of the <b>GameEngine</b> class. </li></ul>
<h4>IDispose</h4>
<p>You may have noticed that some of the classes, such as the <b>Keyboard</b> and
<b>Mouse</b> classes, implement the <b>IDisposable</b> interface. This is an implementation of the Dispose pattern in .NET as explained in the .NET Framework Reference topic
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconFinalizeDispose.asp">
Implementing Finalize and Dispose to Clean Up Unmanaged Resources.</a></p>
<p>The Dispose pattern in .NET is intended to be used when a program makes use of resources that are not managed by the .NET runtime. These &quot;unmanaged&quot; resources need to be cleaned up in a special way to ensure that they are released in a deterministic manner.
 Since the .NET garbage collection is non-deterministic, we need to use a particular set of steps to ensure this cleanup is done correctly. These steps are defined in the Dispose pattern.</p>
<p>We use a lot of unmanaged resources in game development, so it is best to implement the Dispose pattern in every class that interacts with DirectX or file resources (almost all of our classes). This will protect us against memory leaks and increase the performance
 of the game. </p>
<p>You can read the topic mentioned above to get more background information on this pattern and garbage collection for .NET. I have added the Dispose pattern in all of the classes for this article, and will do so going forward.
</p>
<p>What we need in BattleTank 2005 now are units. If you go back to the screenshot of the original game shown in the
<a href="http://blogs.msdn.com/coding4fun/gamedevelopment/beginning/default.aspx">
first article</a>, you see that we need to add shapes and opposing tanks. The shapes are obstacles for you or the enemy tanks to use as cover. The enemy tanks are what we are going to eventually shoot at. These objects also aid us in navigation in the otherwise
 bare landscape. You may remember that we had to write out the camera location to the console to see that we were moving because there were no reference points in the scene. In the next article we will complete the scene by adding some terrain.
</p>
<h4>Units</h4>
<p>For BattleTank 2005 we are going to have two types of 3D objects: Obstacles and Tanks. The main difference between them is that tanks can move and obstacles can not. Since we are going to have lots of obstacles and tanks, we are going to organize them so
 that they can be manipulated in bulk. We do this by adding them to a collection.
</p>
<p>We could add both types of objects to a single collection, but it makes sense to separate each type into its own collection. Separating the objects in this manner allows us to concentrate on a particular group without incurring the overhead of testing each
 unit for its type, which improves performance. We can then update the position of the mobile units while skipping the stationary units.
</p>
<h4>Generics</h4>
<p>In previous versions of .NET, creating a collection class to hold the units and ensuring that it was type-safe was pretty involved. Each collection in .NET 1.0 and 1.1 was a collection of objects. This meant that it accepted any value or reference type,
 making it very flexible. But this also meant that we had to cast the object to its proper type whenever we retrieved an object from the collection. This meant we ran the danger of the object cast failing. Accounting for the possible exception and testing each
 object before the cast incurred more overhead. </p>
<p>With .NET 2.0 we can use Generics to create type-safe collections for us with minimum effort. These collection classes are safer and perform better than regular collection. This is only one of the possible uses of generics, but probably the most common.
</p>
<p>To learn more about generics check out these articles at MSDN: </p>
<ul>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/csharp_generics.asp">An Introduction to C# Generics</a>
</li><li><a href="http://msdn.microsoft.com/msdnmag/issues/03/09/NET/">MSDN Magazine: Introducing Generics in the CLR</a></li></ul>
<p>All units, regardless of their purpose, have a number of things in common. To make the application easier to maintain, we are going to factor all of the common characteristics of the unit into a single base class. All units will derive from the common base
 class and be extended with custom properties and methods. </p>
<p>Creating a base class and derived classes creates an object hierarchy that then allows us to treat all units polymorphically, which is a very powerful concept in object oriented programming. Check out these Visual Studio .NET topics on polymorphism at MSDN:
</p>
<ul>
<li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/vbconinheritancepolymorphismallthat.asp">Visual Basic Reference: Polymorphism</a>
</li><li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbconImplementingInterfacesInComponents.asp">Visual Basic and Visual C# Concepts: Polymorphism in Components</a></li></ul>
<p>The resulting base class looks like this. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">class</span> UnitBase : IDisposable<br>{<br>    <span class="kwrd">public</span> UnitBase (Device device, <span class="kwrd">string</span> meshFile,<br>        Vector3 position, <span class="kwrd">float</span> scale )<br>    <span class="kwrd">public</span> <span class="kwrd">void</span> Render ( Camera camera )<br><br>    <span class="kwrd">public</span> <span class="kwrd">bool</span> IsCulled<br>    <span class="kwrd">public</span> Vector3 Position<br>    <span class="kwrd">public</span> <span class="kwrd">float</span> Radius<br>    <span class="kwrd">private</span> <span class="kwrd">void</span> LoadMesh ( )<br>    <span class="kwrd">private</span> <span class="kwrd">void</span> ComputeRadius ( )<br><br>    <span class="kwrd">private</span> Vector3 _position;<br>    <span class="kwrd">private</span> <span class="kwrd">float</span> _radius;<br>    <span class="kwrd">private</span> <span class="kwrd">bool</span> _isCulled;<br>    <span class="kwrd">private</span> Device _device;<br>    <span class="kwrd">private</span> <span class="kwrd">string</span> _meshFile;<br>    <span class="kwrd">private</span> <span class="kwrd">float</span> _scale;<br>    <span class="kwrd">private</span> Mesh _mesh = <span class="kwrd">null</span>;<br>    <span class="kwrd">private</span> Material[] _meshMaterials;<br>    <span class="kwrd">private</span> Texture[] _meshTextures;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">MustInherit</span> <span class="kwrd">Class</span> UnitBase<br>    <span class="kwrd">Implements</span> IDisposable<br>    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>(<span class="kwrd">ByVal</span> device <span class="kwrd">As</span> Device, _<br>        <span class="kwrd">ByVal</span> meshFile <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> position <span class="kwrd">As</span> Vector3, _<br>        <span class="kwrd">ByVal</span> scale <span class="kwrd">As</span> <span class="kwrd">Single</span>)<br><br>    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Render(<span class="kwrd">ByVal</span> camera <span class="kwrd">As</span> Camera)<br><br>    <span class="kwrd">Public</span> <span class="kwrd">Property</span> IsCulled() <span class="kwrd">As</span> <span class="kwrd">Boolean</span>
    <span class="kwrd">Public</span> <span class="kwrd">Property</span> Position() <span class="kwrd">As</span> Vector3<br>    <span class="kwrd">Public</span> <span class="kwrd">Property</span> X() <span class="kwrd">As</span> <span class="kwrd">Single</span>
    <span class="kwrd">Public</span> <span class="kwrd">Property</span> Y() <span class="kwrd">As</span> <span class="kwrd">Single</span>
    <span class="kwrd">Public</span> <span class="kwrd">Property</span> Z() <span class="kwrd">As</span> <span class="kwrd">Single</span>
    <span class="kwrd">Public</span> <span class="kwrd">ReadOnly</span> <span class="kwrd">Property</span> Radius() <span class="kwrd">As</span> <span class="kwrd">Single</span>
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Dispose() <span class="kwrd">Implements</span> IDisposable.Dispose<br>    <span class="kwrd">Protected</span> <span class="kwrd">Overridable</span> <span class="kwrd">Sub</span> Dispose(<span class="kwrd">ByVal</span> disposing <span class="kwrd">As</span> <span class="kwrd">Boolean</span>)<br>    <span class="kwrd">Protected</span> <span class="kwrd">Overrides</span> <span class="kwrd">Sub</span> Finalize()<br>    <span class="kwrd">Private</span> _disposed <span class="kwrd">As</span> <span class="kwrd">Boolean</span>
    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> LoadMesh()<br>    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> ComputeRadius()<br>    <span class="kwrd">Private</span> m_position <span class="kwrd">As</span> Vector3<br>    <span class="kwrd">Private</span> m_radius <span class="kwrd">As</span> <span class="kwrd">Single</span>
    <span class="kwrd">Private</span> m_isCulled <span class="kwrd">As</span> <span class="kwrd">Boolean</span>
    <span class="kwrd">Private</span> m_device <span class="kwrd">As</span> Device<br>    <span class="kwrd">Private</span> m_meshFile <span class="kwrd">As</span> <span class="kwrd">String</span>
    <span class="kwrd">Private</span> m_scale <span class="kwrd">As</span> <span class="kwrd">Single</span>
    <span class="kwrd">Private</span> m_mesh <span class="kwrd">As</span> Mesh = <span class="kwrd">Nothing</span>
    <span class="kwrd">Private</span> m_meshMaterials <span class="kwrd">As</span> Material()<br>    <span class="kwrd">Private</span> m_meshTextures <span class="kwrd">As</span> Texture()<br><span class="kwrd">End</span> Class</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>While most of this should make sense, you may be wondering what a mesh file is and why we are loading it.
</p>
<h4>3D Modeling</h4>
<p>At some point you realize that creating complex 3D objects in code line by line is pretty silly. The simple cube we created for the skybox alone was almost 200 lines of code. There has to be a better way to create 3D objects.
</p>
<p>Most 3D models are created by artists using dedicated modeling programs such as Maya or 3ds Max. These programs store the information about their models in proprietary file formats (iff for Maya and 3ds for 3DS Max). DirectX can not directly read these file
 formats, but it can read a format called the X file. </p>
<h4>X Files</h4>
<p>DirectX defines a file format called the X file format. It contains the definition for a 3D model. We can use these files to dramatically reduce the amount of code we need to write when loading 3D models into our game by loading them from the X file. In
 DirectX lingo, the X files are mesh files. </p>
<h4>Mesh</h4>
<p>If you remember from our previous article, a mesh is data that describes a 3D shape. Mesh data includes a list of vertices that comprise the shape, information on how the vertices are connected to each other, and texture information for all vertices.
</p>
<p>There are also conversion programs available that convert 3D objects files from other formats into the X file format. The DirectX SDK actually ships with plug-ins for Maya and 3ds Max that allow you to convert files created with these programs into the X
 file format. </p>
<p>So where can you get some X files to start working with? The DirectX SDK includes a folder called Media under the Samples folder which contains a number of X files that you can use. The DirectX SDK also includes a number of utilities that allow you to work
 with the X files such as the DirectX viewer and MeshViewer. All of the utilities are located in the Utilities folder. Check out these and the other utilities that come with the SDK, as they can save you time and effort.
</p>
<p><b>Free 3D models</b>: Unless you are very graphically talented it is probably best for an artist to create the models for your game. There are a large number of free 3D models available on the internet created by artists to show of their skills. Generally
 they don't mind if you use their work for you own gratification, but if you use it in a commercial game, that's a whole other issue. Make sure to read and understand the usage rules for each model before using it. A good site for free models is:
<a href="http://www.3dcafe.com/">http://www.3dcafe.com/</a>. </p>
<p>Using X files with predefined models opens up an entirely new world of integrating 3D objects into our game. No longer do we need to worry abut the low-level details of each object, we can simply load a previously created mesh file.
</p>
<h4>Updating the Skybox</h4>
<p>The first place we are going to use this newfound knowledge is to clean up the skybox code. The SDK includes a file called lobby_skybox.x in the Samples\Media\Lobby folder that describes a cube like the one we are currently using for our sky box. I copied
 this file to the Resources folder as skybox.x and updated the texture files to match the names of our texture files.
</p>
<p><b>Changing textures</b>: Most X files can be opened in a simple text editor. You can search the file for the references to the texture files (look for
<b>TextureFilename</b>) and replace them with your own, or you can substitute your own texture files during the mesh loading phase by passing the texture file name to the
<b>TextureLoader.FromFile</b> method. If you want to see something cool, copy the lobby_skybox.x files and all of the JPG files from the SDK media folder to the resource folder, then change the name of the X file in the skybox LoadMesh method to this X file.
 The resulting skybox is the lobby of the building where all the game developers work at Microsoft.
</p>
<p>In the Skybox class remove the <b>SetupCubeFaces</b> method, the six methods starting with Copy (<b>CopyLeftFaceVertexBuffer</b>,
<b>CopyFrontFaceVertexBuffer</b>, etc.) and the <b>RenderFace</b> method. You can also remove all of the private variables declared at the bottom of the class except for the Device variable. In the
<b>Render</b> method, remove the lines of code that check the Pitch and Heading of the camera. Finally, replace the call to
<b>SetupCubeFaces</b> in the constructor with a call to <b>LoadMesh</b>. </p>
<p>Now add the following three variable declarations at the bottom of the class. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> Mesh _mesh = <span class="kwrd">null</span>;<br><span class="kwrd">private</span> Material[] _meshMaterials;<br><span class="kwrd">private</span> Texture[] _meshTextures;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> m_mesh <span class="kwrd">As</span> Mesh = <span class="kwrd">Nothing</span>
<span class="kwrd">Private</span> m_meshMaterials <span class="kwrd">As</span> Material()<br><span class="kwrd">Private</span> m_meshTextures <span class="kwrd">As</span> Texture()</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We already know what a mesh and a texture is, but what is the material? </p>
<h4>Material</h4>
<p>Materials describe how polygons reflect ambient and diffuse light, as well as information about specular highlights and if the polygons appear to emit light. The main thing to remember is that while textures define how polygons look, materials define how
 they reflect light. </p>
<h4>Loading a Mesh</h4>
<p>Loading the mesh from a file is very simple. All you have to do is to call the
<b>FromFile</b> method of the <b>Mesh</b> class. (You should spend some time to familiarize yourself with the Mesh class and its methods, since it is one of the core classes you will use.)
</p>
<p>In the Skybox class add the following code. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> LoadMesh ( )<br>{<br>    ExtendedMaterial[] materials = <span class="kwrd">null</span>;<br>    Directory.SetCurrentDirectory ( <br>        Application.StartupPath &#43; <span class="str">@&quot;\..\..\..\Resources\&quot; );<br>    _mesh = Mesh.FromFile (@&quot;</span>skybox.x&quot;,<br>        MeshFlags.SystemMemory, _device, <span class="kwrd">out</span> materials);<br>    <span class="kwrd">if</span> ( ( materials != <span class="kwrd">null</span> ) &amp;&amp; ( materials.Length &gt; 0 ) )<br>    {<br>        _meshTextures = <span class="kwrd">new</span> Texture[materials.Length];<br>        _meshMaterials = <span class="kwrd">new</span> Material[materials.Length];<br>        <span class="kwrd">for</span> ( <span class="kwrd">int</span> i = 0 ; i &lt; materials.Length ; i&#43;&#43; )<br>        {<br>            _meshMaterials[i] = materials[i].Material3D;<br>            _meshMaterials[i].Ambient = _meshMaterials[i].Diffuse;<br>            <span class="kwrd">if</span> (materials[i].TextureFilename != <span class="kwrd">null</span> &amp;&amp; <br>                    (materials[i].TextureFilename != <span class="kwrd">string</span>.Empty))<br>                _meshTextures[i] = TextureLoader.FromFile ( _device, <br>                    materials[i].TextureFilename );<br>        }<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> LoadMesh()<br>    <span class="kwrd">Dim</span> materials <span class="kwrd">As</span> ExtendedMaterial() = <span class="kwrd">Nothing</span>
    Directory.SetCurrentDirectory(Application.StartupPath _ 
        &amp; <span class="str">&quot;\..\..\..\Resources\&quot;</span>)<br>    m_mesh = Mesh.FromFile(<span class="str">&quot;skybox.x&quot;</span>, MeshFlags.SystemMemory, _<br>        m_device, materials)<br><br>    <span class="kwrd">If</span> (<span class="kwrd">Not</span> (materials <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>)) <span class="kwrd">AndAlso</span> _<br>        (materials.Length &gt; 0) <span class="kwrd">Then</span>
        m_meshTextures = <span class="kwrd">New</span> Texture(materials.Length) {}<br>        m_meshMaterials = <span class="kwrd">New</span> Material(materials.Length) {}<br>        <span class="kwrd">Dim</span> i <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 0<br>        <span class="kwrd">While</span> i &lt; materials.Length<br>            m_meshMaterials(i) = materials(i).Material3D<br>            m_meshMaterials(i).Ambient = m_meshMaterials(i).Diffuse<br>            <span class="kwrd">If</span> <span class="kwrd">Not</span> (materials(i).TextureFilename <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">AndAlso</span> _<br>                    (<span class="kwrd">Not</span> (materials(i).TextureFilename = <span class="kwrd">String</span>.Empty)) <span class="kwrd">Then</span>
                m_meshTextures(i) = TextureLoader.FromFile( _
                    m_device, materials(i).TextureFilename)
            <span class="kwrd">End</span> <span class="kwrd">If</span>
            System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)
        <span class="kwrd">End</span> <span class="kwrd">While</span>
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>While DirectX handles most of the work of reading the X file and converting it into an object for us (i.e. the creation of the vertex and index buffers etc.) we have to manually manage loading the materials and textures for the mesh.
</p>
<p>The last step to integrate the X file and textures into the Skybox is to modify the
<b>Render</b> method of the <b>Skybox</b> class. Immediately after the <code>_device.RenderState.CullMode = Microsoft.DirectX.Direct3D.Cull.None;</code> line add the following code.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">for</span> ( <span class="kwrd">int</span> i = 0 ; i &lt; _meshMaterials.Length ; i&#43;&#43; )<br>{<br>    _device.Material = _meshMaterials[i];<br>    _device.SetTexture ( 0, _meshTextures[i] );<br>    _mesh.DrawSubset ( i );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">While</span> i &lt; m_meshMaterials.Length<br>    m_device.Material = m_meshMaterials(i)<br>    m_device.SetTexture(0, m_meshTextures(i))<br>    m_mesh.DrawSubset(i)<br>    System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)<br><span class="kwrd">End</span> While</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Once again we iterate over the <b>meshMaterials</b> and then call the <b>DrawSubset</b> method of the
<b>Mesh</b> to draw each subset in turn. That's it; the entire <b>Skybox</b> class is now only about 80 lines long and much easier to read.
</p>
<p>Returning to the <b>UnitBase</b> class, the next item we need to look at is the
<b>IsCulled</b> flag. </p>
<h4>Culling</h4>
<p>We briefly covered culling in the third article. Culling is simply the removal of entire objects from the scene so they will not be rendered. The logic to determine what objects should be removed can range from the very simple to the very complex. In BattleTank
 2005 we are going to cull all of the objects that do not fall into the view frustum of the scene.
</p>
<p>To determine if the unit is in the view frustum, we enhance the <b>Camera</b> class to provide us the info about the current view frustum so that we can check each object and see if it falls inside or outside of the frustum. To perform this check, we use
 the <b>Radius</b> property of the <b>UnitBase</b> class which is computed in the ComputeRadius method.
</p>
<p>The <b>BoundingSphere</b> method of the <b>Geometry</b> class (the same one we use now for converting radians to degrees and vice versa) computes a sphere that completely contains all the points in the mesh using a vertex data of the mesh. The mesh contains
 this information in the vertex buffer. To access this buffer, it is best to lock it before access and unlock it when done. You should also make sure to dispose the vertex buffer when you are done. The safest way to do this is to leverage the
<code>using</code> statement that will ensure that <b>Dispose</b> is called regardless of what happens.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ComputeRadius ( )<br>{<br>    <span class="kwrd">using</span> ( VertexBuffer vertexBuffer = _mesh.VertexBuffer )<br>    {<br>        GraphicsStream gStream = vertexBuffer.Lock ( 0, 0,<br>            LockFlags.None );<br>        Vector3 tempCenter;<br><br>        _radius = Geometry.ComputeBoundingSphere (gStream,<br>            _mesh.NumberVertices, _mesh.VertexFormat, <br>            <span class="kwrd">out</span> tempCenter ) * _scale;<br><br>        vertexBuffer.Unlock ( );<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> ComputeRadius()<br>    <span class="kwrd">Dim</span> vertexBuffer <span class="kwrd">As</span> VertexBuffer = <span class="kwrd">Nothing</span>
    <span class="kwrd">Try</span>
        vertexBuffer = m_mesh.VertexBuffer
        <span class="kwrd">Dim</span> gStream <span class="kwrd">As</span> GraphicsStream = _<br>            vertexBuffer.Lock(0, 0, LockFlags.None)<br>        <span class="kwrd">Dim</span> tempCenter <span class="kwrd">As</span> Vector3<br>        m_radius = Geometry.ComputeBoundingSphere(gStream, _<br>            m_mesh.NumberVertices, m_mesh.VertexFormat, tempCenter) * _<br>            m_scale<br>    <span class="kwrd">Finally</span>
        vertexBuffer.Unlock()
        vertexBuffer.Dispose()
    <span class="kwrd">End</span> <span class="kwrd">Try</span>
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can probably understand why using the radius of the object is a very rough way of culling objects. It works fine and is fairly accurate if the objects are simple shapes, but for more complex shapes the bounding sphere becomes much larger than the basic
 object itself. </p>
<p>In a commercial game a lot of effort is invested in creating a culling routine that eliminates the most objects it can. We could also get fancy here and identify objects that are only partially in the frustum, but without the corresponding ability to render
 only a portion of the unit, we are just wasting our time. Instead we will treat any unit that has even a single point in the view frustum as being completely in the frustum.
</p>
<p>So now that we have the radius of the unit, we need to know what the frustum is so we can check the radius against it.
</p>
<h4>View Frustum</h4>
<p>Adding the frustum info to the camera is easy. First we add some data structures to hold the information about the view frustum. If you recall from the previous article, a frustum resembles a pyramid with the top cut off. This means that we need to store
 the corners of the top and bottom square and the plane for each side. For the corners we use an array of the familiar
<b>Vector3</b> structure. For the planes DirectX provides a convenient <b>Plane</b> structure.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> Vector3[] _frustumCorners;<br><span class="kwrd">private</span> Plane[] _frustumPlanes;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> Vector3[] _frustumCorners;<br><span class="kwrd">private</span> Plane[] _frustumPlanes;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We then initialize the arrays in the constructor (two squares with four corners equals 8 points, and the four sides of the polygon plus the top and bottom make six planes).
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_frustumCorners = <span class="kwrd">new</span> Vector3[8];<br>_frustumPlanes = <span class="kwrd">new</span> Plane[6];</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">m_frustumCorners = New Vector3(8) {}<br>m_frustumPlanes = New Plane(6) {}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The next step is to compute the frustum using the current view and projection matrices.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> ComputeViewFrustum ( )<br>{<br>    Matrix matrix = _viewMatrix * _perspectiveMatrix;<br>    matrix.Invert ( );<br><br>    _frustumCorners[0] = <span class="kwrd">new</span> Vector3 ( -1.0f, -1.0f, 0.0f ); <span class="rem">// xyz</span>
    _frustumCorners[1] = <span class="kwrd">new</span> Vector3 ( 1.0f, -1.0f, 0.0f ); <span class="rem">// Xyz</span>
    _frustumCorners[2] = <span class="kwrd">new</span> Vector3 ( -1.0f, 1.0f, 0.0f ); <span class="rem">// xYz</span>
    _frustumCorners[3] = <span class="kwrd">new</span> Vector3 ( 1.0f, 1.0f, 0.0f ); <span class="rem">// XYz</span>
    _frustumCorners[4] = <span class="kwrd">new</span> Vector3 ( -1.0f, -1.0f, 1.0f ); <span class="rem">// xyZ</span>
    _frustumCorners[5] = <span class="kwrd">new</span> Vector3 ( 1.0f, -1.0f, 1.0f ); <span class="rem">// XyZ</span>
    _frustumCorners[6] = <span class="kwrd">new</span> Vector3 ( -1.0f, 1.0f, 1.0f ); <span class="rem">// xYZ</span>
    _frustumCorners[7] = <span class="kwrd">new</span> Vector3 ( 1.0f, 1.0f, 1.0f ); <span class="rem">// XYZ</span>
    <span class="kwrd">for</span> ( <span class="kwrd">int</span> i = 0 ; i &lt; _frustumCorners.Length ; i&#43;&#43; )<br>        _frustumCorners[i] = Vector3.TransformCoordinate (<br>            _frustumCorners[i], matrix );<br><br>    <span class="rem">// Now calculate the planes</span>
    _frustumPlanes[0] = Plane.FromPoints (
        _frustumCorners[0], 
        _frustumCorners[1], 
        _frustumCorners[2] ); <span class="rem">// Near</span>
    _frustumPlanes[1] = Plane.FromPoints ( 
        _frustumCorners[6], 
        _frustumCorners[7], 
        _frustumCorners[5] ); <span class="rem">// Far</span>
    _frustumPlanes[2] = Plane.FromPoints ( 
        _frustumCorners[2], 
        _frustumCorners[6], 
        _frustumCorners[4] ); <span class="rem">// Left</span>
    _frustumPlanes[3] = Plane.FromPoints ( 
        _frustumCorners[7], 
        _frustumCorners[3], 
        _frustumCorners[5] ); <span class="rem">// Right</span>
    _frustumPlanes[4] = Plane.FromPoints ( 
        _frustumCorners[2], 
        _frustumCorners[3], 
        _frustumCorners[6] ); <span class="rem">// Top</span>
    _frustumPlanes[5] = Plane.FromPoints ( 
        _frustumCorners[1], 
        _frustumCorners[0], 
        _frustumCorners[4] ); <span class="rem">// Bottom</span>
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> ComputeViewFrustum()<br>    <span class="kwrd">Dim</span> matrix <span class="kwrd">As</span> Matrix = m_viewMatrix * m_perspectiveMatrix<br>    matrix.Invert()<br>    m_frustumCorners(0) = <span class="kwrd">New</span> Vector3(-1.0F, -1.0F, 0.0F)<br>    m_frustumCorners(1) = <span class="kwrd">New</span> Vector3(1.0F, -1.0F, 0.0F)<br>    m_frustumCorners(2) = <span class="kwrd">New</span> Vector3(-1.0F, 1.0F, 0.0F)<br>    m_frustumCorners(3) = <span class="kwrd">New</span> Vector3(1.0F, 1.0F, 0.0F)<br>    m_frustumCorners(4) = <span class="kwrd">New</span> Vector3(-1.0F, -1.0F, 1.0F)<br>    m_frustumCorners(5) = <span class="kwrd">New</span> Vector3(1.0F, -1.0F, 1.0F)<br>    m_frustumCorners(6) = <span class="kwrd">New</span> Vector3(-1.0F, 1.0F, 1.0F)<br>    m_frustumCorners(7) = <span class="kwrd">New</span> Vector3(1.0F, 1.0F, 1.0F)<br>    <span class="kwrd">Dim</span> i <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 0<br>    <span class="kwrd">While</span> i &lt; m_frustumCorners.Length<br>        m_frustumCorners(i) = _<br>            Vector3.TransformCoordinate(m_frustumCorners(i), matrix)<br>        System.Math.Min( _<br>            System.Threading.Interlocked.Increment(i), i - 1)<br>    <span class="kwrd">End</span> <span class="kwrd">While</span>
    m_frustumPlanes(0) = Plane.FromPoints(m_frustumCorners(0), 
        m_frustumCorners(1), m_frustumCorners(2))
    m_frustumPlanes(1) = Plane.FromPoints( _
        m_frustumCorners(6), _
        m_frustumCorners(7), _
        m_frustumCorners(5))
    m_frustumPlanes(2) = Plane.FromPoints( _
        m_frustumCorners(2), _
        m_frustumCorners(6), _
        m_frustumCorners(4))
    m_frustumPlanes(3) = Plane.FromPoints( _
        m_frustumCorners(7), _
        m_frustumCorners(3), _
        m_frustumCorners(5))
    m_frustumPlanes(4) = Plane.FromPoints( _
        m_frustumCorners(2), _
        m_frustumCorners(3), _
        m_frustumCorners(6))
    m_frustumPlanes(5) = Plane.FromPoints( _
        m_frustumCorners(1), _
        m_frustumCorners(0), _
        m_frustumCorners(4))
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>First we combine the view and projection matrices by multiplying them. Next we initialize the eight corners of the frustum as a cube immediately in front of the camera. These corners are then transformed and used to create the 6 planes using the
<b>FromPoints</b> method of the plane. </p>
<p>The frustum is computed upon initialization of the class and on each render loop. Add a call to
<b>ComputeViewFrustum( )</b> to the bottom of the constructor of the <b>Camera</b> class and at the end of the
<b>Render</b> method of the <b>Camera</b> class. (It needs to be at the end so it can use the newly computed view and projection matrices.) Now we can use the computed frustum and the radius for each unit to determine whether any part of the unit is in the
 frustum and should be rendered. The <b>IsInViewFrustum</b> method returns true if the unit is inside the frustum and false otherwise.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">bool</span> IsInViewFrustum ( UnitBase unitToCheck )<br>{<br>    <span class="kwrd">foreach</span> ( Plane plane <span class="kwrd">in</span> _frustumPlanes )<br>    {<br>        <span class="kwrd">if</span> ( plane.A * unitToCheck.Position.X &#43; plane.B *<br>             unitToCheck.Position.Y &#43; plane.C * unitToCheck.Position.Z &#43; <br>             plane.D &lt;= ( -unitToCheck.Radius ) )<br>        <span class="kwrd">return</span> <span class="kwrd">false</span>;<br>    }<br>    <span class="kwrd">return</span> <span class="kwrd">true</span>;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Function</span> IsInViewFrustum(<span class="kwrd">ByVal</span> unitToCheck <span class="kwrd">As</span> UnitBase) <span class="kwrd">As</span> <span class="kwrd">Boolean</span>
    <span class="kwrd">For</span> <span class="kwrd">Each</span> plane <span class="kwrd">As</span> Plane <span class="kwrd">In</span> m_frustumPlanes<br>        <span class="kwrd">If</span> plane.A * unitToCheck.Position.X &#43; plane.B * _<br>            unitToCheck.Position.Y &#43; plane.C * unitToCheck.Position.Z &#43; _<br>            plane.D &lt;= (-unitToCheck.Radius) <span class="kwrd">Then</span>
            <span class="kwrd">Return</span> <span class="kwrd">False</span>
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">Next</span>
    <span class="kwrd">Return</span> <span class="kwrd">True</span>
<span class="kwrd">End</span> Function</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The process of culling should take place before the unit is rendered. We accomplish this in the
<b>Render</b> method of the <b>BaseUnit</b> class by checking the frustum of the camera before actually rendering the mesh. By placing it into the actual
<b>Render</b> method, we avoid having to check the cull state elsewhere in the code.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> (camera.IsInViewFrustum ( <span class="kwrd">this</span> ) == <span class="kwrd">false</span> )<br>    <span class="kwrd">return</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> camera.IsInViewFrustum(<span class="kwrd">Me</span>) = <span class="kwrd">False</span> <span class="kwrd">Then</span>
    <span class="kwrd">Return</span>
<span class="kwrd">End</span> If</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now that we have the basic infrastructure in place, it's time to start adding units. But the
<b>UnitBase</b> class is abstract, so it can not be instantiated. The entire purpose of the base class was to keep common unit properties and functionality together. Now it's time to create some classes that represent the objects we are going to use in BattleTank
 2005, namely obstacles and tanks. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Obstacle : UnitBase<br>{<br>    <span class="kwrd">public</span> Obstacle ( Device device, <span class="kwrd">string</span> meshFile, <br>        Vector3 position, <span class="kwrd">float</span> scale )<br>         : <span class="kwrd">base</span> ( device, meshFile, position, scale )<br>    {<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"></pre>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Class</span> Obstacle<br>    <span class="kwrd">Inherits</span> UnitBase<br><br>    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>(<span class="kwrd">ByVal</span> device <span class="kwrd">As</span> Device, <span class="kwrd">ByVal</span> meshFile <span class="kwrd">As</span> <span class="kwrd">String</span>, _<br>    <span class="kwrd">ByVal</span> position <span class="kwrd">As</span> Vector3, <span class="kwrd">ByVal</span> scale <span class="kwrd">As</span> <span class="kwrd">Single</span>)<br>        <span class="kwrd">MyBase</span>.<span class="kwrd">New</span>(device, meshFile, position, scale)<br>    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> Class</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <b>Obstacle</b> class currently does nothing more than call its base class, but we are going add to this class later on.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Tank : UnitBase<br>{<br>    <span class="kwrd">public</span> Tank ( Device device, <span class="kwrd">string</span> meshFile, <br>        Vector3 position, <span class="kwrd">float</span> scale ) <br>        : <span class="kwrd">base</span> ( device, meshFile, position, scale )<br>    <span class="kwrd">public</span> <span class="kwrd">void</span> Update ( <span class="kwrd">float</span> deltaTime )<br>    <span class="kwrd">private</span> <span class="kwrd">float</span> _speed = 10.0f;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Class</span> Tank<br>    <span class="kwrd">Inherits</span> UnitBase<br><br>    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>(<span class="kwrd">ByVal</span> device <span class="kwrd">As</span> Device, <span class="kwrd">ByVal</span> meshFile <span class="kwrd">As</span> <span class="kwrd">String</span>, _<br>        <span class="kwrd">ByVal</span> position <span class="kwrd">As</span> Vector3, <span class="kwrd">ByVal</span> scale <span class="kwrd">As</span> <span class="kwrd">Single</span>)<br>        <span class="kwrd">MyBase</span>.<span class="kwrd">New</span>(device, meshFile, position, scale)<br>    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Update(<span class="kwrd">ByVal</span> deltaTime <span class="kwrd">As</span> <span class="kwrd">Single</span>)<br>        <span class="kwrd">MyBase</span>.Z -= (m_speed * deltaTime)<br>    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    <span class="kwrd">Private</span> m_speed <span class="kwrd">As</span> <span class="kwrd">Single</span> = 10.0F<br><span class="kwrd">End</span> Class</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <b>Tank</b> class adds a <code>_speed</code> property we need to describe and an
<b>Update</b> method. </p>
<h4>Using time to simulate movement</h4>
<p>The <b>Update</b> method takes in a float that describes the amount of time in seconds that has passed since the last render loop. In the second article we added a variable called
<b>deltaTime</b> which we used to compute the frame rate. This value is the value we want to use from now on to compute the position of moving objects. We use the principle of time to ensure a similar experience on each computer regardless of the speed of the
 computer and make the movement appear fluid. For example, if we updated the position of a moving object by 1 in each pass through the render loop, the object would move fast on faster computers since they are able to complete a render loop faster. You may
 have seen this behavior when experimenting with the rotating cube. Another problem is that each pass through the render loop is not performed at the same speed, depending on the other operations the CPU is performing, so that the movement may appear choppy.
 (Again, the easiest way to understand this is to experiment. Change the increment of the Z axis by one instead of the speed * time formula and see what happens.)
</p>
<p>Notice that we only need to update the tanks since the obstacles do not move. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">foreach</span> ( Tank tank <span class="kwrd">in</span> _tanks )<br>{<br>    tank.Update ( _deltaTime );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">For</span> <span class="kwrd">Each</span> tank <span class="kwrd">As</span> Tank <span class="kwrd">In</span> m_tanks<br>    tank.Update(m_deltaTime)<br>Next</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The actual <b>Update</b> method in the tank simply moves the tank towards the origin for now, using a predefined speed.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Update ( <span class="kwrd">float</span> deltaTime )<br>{<br>    <span class="kwrd">base</span>.Z -= ( _speed * deltaTime );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> Update(<span class="kwrd">ByVal</span> deltaTime <span class="kwrd">As</span> <span class="kwrd">Single</span>)<br>    <span class="kwrd">MyBase</span>.Z -= (m_speed * deltaTime)<br><span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next we create two generic collections in the <b>GameEngine</b> class to hold the mobile and stationery units.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> List&lt;UnitBase&gt; _obstacles;<br><span class="kwrd">private</span> List&lt;UnitBase&gt; _tanks;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> List&lt;UnitBase&gt; _obstacles;<br><span class="kwrd">private</span> List&lt;UnitBase&gt; _tanks;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The actual units are added to the collection in the <b>CreateObstacles</b> and
<b>CreateTanks</b> methods. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> CreateObstacles ( )<br>{<br>    _obstacles = <span class="kwrd">new</span> List&lt;UnitBase&gt; ( );<br>    _obstacles.Add ( <span class="kwrd">new</span> Obstacle ( _device, <span class="str">@&quot;car.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( 0, 0, 200 ), 1f ) );<br>    _obstacles.Add ( <span class="kwrd">new</span> Obstacle ( _device, <span class="str">@&quot;car.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( 60, 0, 100 ), 1f ) );<br>    _obstacles.Add ( <span class="kwrd">new</span> Obstacle ( _device, <span class="str">@&quot;car.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( -60, 0, 150 ), 1f ) );<br>    _obstacles.Add ( <span class="kwrd">new</span> Obstacle ( _device, <span class="str">@&quot;car.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( 60, 0, -100 ), 1f ) );<br>    _obstacles.Add ( <span class="kwrd">new</span> Obstacle ( _device, <span class="str">@&quot;car.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( -60, 0, -150 ), 1f ) );<br>}<br><br><span class="kwrd">private</span> <span class="kwrd">void</span> CreateTanks ( )<br>{<br>    _tanks = <span class="kwrd">new</span> List&lt;UnitBase&gt; ( );<br>    _tanks.Add ( <span class="kwrd">new</span> Tank (_device, <span class="str">@&quot;bigship1.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( 0, 0, 200 ), 1f ) );<br>    _tanks.Add ( <span class="kwrd">new</span> Tank (_device, <span class="str">@&quot;bigship1.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( 100, 0, 300 ), 1f ) );<br>    _tanks.Add ( <span class="kwrd">new</span> Tank (_device, <span class="str">@&quot;bigship1.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( -100, 0, 500 ), 1f ) );<br>    _tanks.Add ( <span class="kwrd">new</span> Tank (_device, <span class="str">@&quot;bigship1.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( 100, 0, -200 ), 1f ) );<br>    _tanks.Add ( <span class="kwrd">new</span> Tank (_device, <span class="str">@&quot;bigship1.x&quot;</span>, <br>        <span class="kwrd">new</span> Vector3 ( -100, 0, -400 ), 1f ) );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> CreateObstacles()<br>    m_obstacles = <span class="kwrd">New</span> List(Of UnitBase)()<br>    m_obstacles.Add(<span class="kwrd">New</span> Obstacle(m_device, <span class="str">&quot;car.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(0, 0, 200), 1.0F))<br>    m_obstacles.Add(<span class="kwrd">New</span> Obstacle(m_device, <span class="str">&quot;car.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(60, 0, 100), 1.0F))<br>    m_obstacles.Add(<span class="kwrd">New</span> Obstacle(m_device, <span class="str">&quot;car.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(-60, 0, 150), 1.0F))<br>    m_obstacles.Add(<span class="kwrd">New</span> Obstacle(m_device, <span class="str">&quot;car.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(60, 0, -100), 1.0F))<br>    m_obstacles.Add(<span class="kwrd">New</span> Obstacle(m_device, <span class="str">&quot;car.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(-60, 0, -150), 1.0F))<br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">Private</span> <span class="kwrd">Sub</span> CreateTanks()<br>    m_tanks = <span class="kwrd">New</span> List(Of UnitBase)<br>    m_tanks.Add(<span class="kwrd">New</span> Tank(m_device, <span class="str">&quot;bigship1.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(0, 0, 200),1.0F))<br>    m_tanks.Add(<span class="kwrd">New</span> Tank(m_device, <span class="str">&quot;bigship1.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(100, 0, 300), 1.0F))<br>    m_tanks.Add(<span class="kwrd">New</span> Tank(m_device, <span class="str">&quot;bigship1.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(-100, 0, 500), 1.0F))<br>    m_tanks.Add(<span class="kwrd">New</span> Tank(m_device, <span class="str">&quot;bigship1.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(100, 0, -200), 1.0F))<br>    m_tanks.Add(<span class="kwrd">New</span> Tank(m_device, <span class="str">&quot;bigship1.x&quot;</span>, _<br>        <span class="kwrd">New</span> Vector3(-100, 0, -400), 1.0F))<br><span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you look at the coordinates for the obstacles and tanks, you will see that I placed them along similar axes to help me orient myself. You could also modify these methods to create a random number of obstacles and tanks placed at random coordinates. Just
 make sure to add logic to avoid objects overlapping each other or being too close to the origin and obscuring the camera.
</p>
<h4>Levels</h4>
<p>A more flexible and extensible solution is to read the number, type and location of obstacles and tanks from a file. This file could also contain other play-specific settings and be loaded automatically based on some internal logic. The most common use of
 this scenario is for predefined levels. A player would have the ability to advance to more difficult levels after meeting some completion criteria. This allows you to easily create an ever-changing play experience and fine-tune the playability of each level,
 something you can't do with random placement. Setting the game up that way also allows players to customize the game for themselves. You would normally provide a level editor when following this route.
</p>
<p>The final step is to call these methods. The best place is the constructor of the
<b>GameEngine</b> class right after the <b>Camera</b> class is created. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">public</span> GameEngine ()<br>{<br>    InitializeComponent ( );<br>    <span class="kwrd">this</span>.SetStyle (ControlStyles.AllPaintingInWmPaint | <br>                    ControlStyles.Opaque, <span class="kwrd">true</span> );<br>    ConfigureInputDevices ( );<br>    ConfigureDevice ( );<br>    _skyBox = <span class="kwrd">new</span> SkyBox ( <span class="kwrd">this</span>._device );<br>    _camera = <span class="kwrd">new</span> Camera ( );<br>    CreateObstacles ( );<br>    CreateTanks ( );<br>    <span class="kwrd">this</span>.Size = <span class="kwrd">new</span> Size ( 800, 600 );<br>    HiResTimer.Start ( );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>()<br>    InitializeComponent()<br>    <span class="kwrd">Me</span>.SetStyle(ControlStyles.AllPaintingInWmPaint <span class="kwrd">Or</span> _<br>        ControlStyles.Opaque, <span class="kwrd">True</span>)<br>    ConfigureInputDevices()<br>    ConfigureDevice()<br>    m_skyBox = <span class="kwrd">New</span> SkyBox(<span class="kwrd">Me</span>.m_device)<br>    m_camera = <span class="kwrd">New</span> Camera<br>    CreateObstacles()<br>    CreateTanks()<br>    <span class="kwrd">Me</span>.Size = <span class="kwrd">New</span> Size(800, 600)<br>    HiResTimer.Start()<br><span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>On each render loop all we have to do is to iterate over the appropriate collection and render those that are in the frustum. We call the
<b>RenderUnits</b> method in the <b>Render</b> method of the <b>GameEngine</b> class immediately after rendering the skybox.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> RenderUnits ( )<br>{<br>    <span class="kwrd">foreach</span> ( UnitBase ub <span class="kwrd">in</span> _obstacles )<br>    {<br>        ub.Render ( _camera );<br>    }<br><br>    <span class="kwrd">foreach</span> ( UnitBase ub <span class="kwrd">in</span> _tanks )<br>   {<br>        ub.Render ( _camera );<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> RenderUnits()<br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> ub <span class="kwrd">As</span> UnitBase <span class="kwrd">In</span> m_obstacles<br>        ub.Render(m_camera)<br>    <span class="kwrd">Next</span>
    <span class="kwrd">For</span> <span class="kwrd">Each</span> ub <span class="kwrd">As</span> UnitBase <span class="kwrd">In</span> m_tanks<br>        ub.Render(m_camera)<br>    <span class="kwrd">Next</span>
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>That's all. Now we have units. </p>
<h4>Conclusion</h4>
<p>If you run the game now you will notice three things. </p>
<ul>
<li>The units seem to float in mid-space. </li><li>The units are all white. </li><li>You can drive right through each unit. </li></ul>
<p>The first problem can be solved by adding a terrain to the game to show a solid surface along the Y axis. The second problem can be solved by adding lights to the scene. The final issue will be solved once we add collision detection to the game. Other then
 these items, the game is getting more playable by the day. In the next article we are going to add the missing terrain using a heightmap, add lights so we can see the colors of the units, and add some collision detection.
</p>
<p>As you may have noticed, I have changed (and will continue to do so) the various graphics in the game from article to article. This is intended to encourage you to implement your own graphics to change the underlying game into something completely different.
 You could easily change this game to be set in space, or turn it into a powerboat racing game by just changing the graphics. Give it a try.
</p>
<p>As usual, I ran out of time. In the last article I had promised to add the HUD back, but I ran out of space. I will try to accomplish this in the coming articles. I also wanted to discuss Action mapping to enhance the way we are tracking the keyboard and
 mouse inputs, but this subject will have to be covered in a later article. In addition, I am planning to add a simple debugging console to the game.
</p>
<p>Along with these features, the next articles are going to discuss adding Artificial Intelligence to the opposing tanks, making our game conform to realistic physical forces, and some cool sounds to make playing the game more fun. So stay tuned.
</p>
<p>Until then: Happy coding.</p>
<span>]]&gt;</span> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:c48ff79c952a49ecb51e9e7600d9606b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-V-Adding-Units</comments>
      <itunes:summary>



&amp;nbsp;
This is Part 5 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers adding of 3D objects to the game using predefined mesh files and implementing
 some simple culling.



Derek Pierson
3Leaf Development

Difficulty: Intermediate
Time Required: 
3-6 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions,
DirectX SDK
Hardware: None
Download: 

C# Download
VB Download






Beginning Game Development Series


Beginning Game Development Part 1 - Introduction

Beginning Game Development Part II - Introduction to DirectX

Beginning Game Development: Part III - DirectX II

Beginning Game Development: Part IV - DirectInput

Beginning Game Development: Part V - Adding Units


Beginning Game Development: Part VI - Lights, Materials and Terrain

Beginning Game Development: Part VII –Terrain and Collision Detection

Beginning Game Development: Part VIII - DirectSound


Beginning Game Development: Part VIII - DirectSound II




Beginning Game Development: Part VIII - DirectSound III



Welcome to the fifth article on beginning game development. At this point we have a working 3D environment and can manipulate the camera direction and location using the keyboard and mouse. In this article we are going to add 3D objects to the game using
 predefined mesh files and implement some simple culling. 
Code cleanup
The cleanup in this article consists mainly of fixing the navigation keys and removing some items we no longer need. The following changes have already been integrated into the code for this article:
 

Replaced the radian/degree conversion methods in the Camera class with the utility classes in the
Geometry class. Fixed the key assignments in the CheckForInput method in the GameEngine class so that:

W and S adjust the Z-axis. W is forward (positive) and S backward (negative) A and D adjust the X-axis. A is left (negative) and D is right (positive). Q and Z adjust the Y-axis. Q </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-V-Adding-Units</link>
      <pubDate>Fri, 03 Nov 2006 08:03:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-V-Adding-Units</guid>      
      <dc:creator>Derek Pierson</dc:creator>
      <itunes:author>Derek Pierson</itunes:author>
      <slash:comments>7</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-V-Adding-Units/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Beginning Game Development: Part IV - DirectInput</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This is Part 4 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers the input device portion of DirectX, called DirectInput.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Derek Pierson</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
3-6 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a>,
<a href="http://www.microsoft.com/windows/directx/default.mspx">DirectX SDK</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">None</span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/940908/BattleTank2005CS.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/940908/BattleTank2005VB.msi">VB Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<div class="entry_details"><strong>Beginning Game Development Series</strong></div>
<ol>
<li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx">Beginning Game Development Part 1 - Introduction</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940223.aspx">Beginning Game Development Part II - Introduction to DirectX</a></div>
</li><li>
<div class="entry_details"><a class="" title="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx " href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx">Beginning Game Development: Part III - DirectX II</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940908.aspx">Beginning Game Development: Part IV - DirectInput</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx">Beginning Game Development: Part V - Adding Units</a>
</div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044115.aspx">Beginning Game Development: Part VI - Lights, Materials and Terrain</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044454.aspx">Beginning Game Development: Part VII –Terrain and Collision Detection</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx">Beginning Game Development: Part VIII - DirectSound</a></div>
</li><li>
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2007/11/02/5849691.aspx">Beginning Game Development: Part VIII - DirectSound II</a></div>
</div>
</li><li>
<div class="entry_details">
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7020067.aspx">Beginning Game Development: Part VIII - DirectSound III</a></div>
</div>
</div>
</li></ol>
<p>Welcome to the fourth article on beginning game development. In this article we are going to cover the input device portion of DirectX, called DirectInput. Using DirectInput you can control joysticks, a mouse or the keyboard.
</p>
<p>Before we start I need to cover a couple of items that were brought to my attention via feedback from the readers (thank you everyone for taking the time to do this) and changes not directly related to the items covered in this article.
</p>
<h5>Code Cleanup</h5>
<p>To make adding the code for this section easier and to make the code more reusable I have moved some of the code from the
<b>GameEngine</b> class into separate classes such as <b>Camera</b>. Encapsulating the camera functionality in a separate object makes the code easer to change and to read. The following changes have already been integrated into the code for this article.
</p>
<ol>
<li>I moved the <b>FrameworkTimer</b> class out of the DirectX support code into a class called
<b>HiResTimer</b> and removed the <b>using</b> statements for <b>Microsoft.Samples.DirectX.UtilityToolkit</b>. For the VB version I converted the
<b>FrameworkTimer</b> class into VB and removed the reference to the DirectX Sample Framework library.
</li><li>I refactored the device creation code in the constructor of the <b>GameEngine</b> class into the
<b>ConfigureDevice</b> method. </li><li>I refactored all code that deals with the device in the <b>OnPaint</b> method of the
<b>GameEngine</b> class into the <b>Render</b> method. </li><li>I refactored the code that sets up the camera in the <b>OnPaint</b> method of the
<b>GameEngine</b> class into the <b>Camera</b> class. </li><li>I removed the <b>CreateCrossHairVertexArrayTop</b>, <b>CreateCrossHairVertexArrayBottom,</b>
<b>CreateTestTriangle</b>, and <b>CreateTestCube</b> methods from the <b>GameEngine</b> Class.
</li><li>Removed the <b>System.Collections.Generic</b>, <b>System.ComponentModel</b>, <b>
System.Data</b> and <b>System.Text</b> using statements from the <b>GameEngine</b> class.
</li><li>I removed all of the code used for experimenting with the camera settings. </li></ol>
<p>In addition to these general housekeeping changes I added some code that I needed to make the DirectInput portion more interesting.
</p>
<h5>Skybox</h5>
<p>The infinite 3D space we have created has one problem: it's infinite. We have no distinguishing terrain features to orient us and, as such, have no idea in which direction we are facing. We could create a number of complex 3D objects to draw a realistic
 terrain, but this is very slow and we really do not need 'real' terrain, but only to create the look of real terrain. To create this illusion of seeing a horizon and terrain in the distance, we make use of a technique called the skybox. A skybox creates the
 effect you get when placing your head into a cardboard box, the inside of which is painted with a landscape: Regardless where you are and where you look you see the inside of the box and nothing else.
</p>
<p>In our game we create a cube and display textures (or pictures for us that prefer to use more normal definitions) on the inside walls of the cube. The top would be textured like the sky, the bottom like the ground and the remaining four sides have a texture
 applied to them that shows a horizon and terrain. The pictures for the four sides are designed in such a manner that they match perfectly at the edges and produce a seamless landscape. These four sides could then represent cardinal directions such as east,
 west, north and south (if your game is set on Earth). </p>
<p>To achieve the correct effect, we need to ensure that all objects are drawn on top of the skybox. This is done by disabling Z-buffering before drawing the skybox and enabling it after we are done.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.RenderState.ZBufferWriteEnable = <span class="kwrd">false</span>; <br><span class="rem">// draw the skybox here </span><br>_device.RenderState.ZBufferWriteEnable = <span class="kwrd">true</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"></pre>
<pre class="csharpcode">_device.RenderState.ZBufferWriteEnable = <span class="kwrd">False</span><br><span class="rem">'draw the skybox here</span><br>_device.RenderState.ZBufferWriteEnable = <span class="kwrd">True</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The next thing we need to ensure is that the player can never actually get close to or beyond the skybox (otherwise they would notice the illusion). We accomplish this by ensuring that the viewpoint is always in the center of the skybox.
</p>
<p>First we assign an Identity matrix to the world matrix. Since the vertices of the skybox are in model space (offset around zero), this ensures that they are not translated into world space. Then we set the use the View matrix of the camera to set the View
 matrix of the skybox. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">Matrix worldMatrix = Matrix.Identity;<br>Matrix viewMatrix = cam.View;<br><br>viewMatrix.M41 = 0.0f;<br>viewMatrix.M42 = 0.0f;<br>viewMatrix.M43 = 0.0f;<br><br>_device.Transform.View = viewMatrix;<br>_device.Transform.World = worldMatrix;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Dim</span> worldMatrix <span class="kwrd">As</span> Matrix = Matrix.Identity<br><span class="kwrd">Dim</span> viewMatrix <span class="kwrd">As</span> Matrix = cam.View<br>viewMatrix.M41 = 0.0F<br>viewMatrix.M42 = 0.0F<br>viewMatrix.M43 = 0.0F<br>_device.Transform.View = viewMatrix<br>_device.Transform.World = worldMatrix</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Drawing the actual skybox uses the techniques we have discussed in the previous articles and I am not going to cover them in detail. The basic steps are as follows.
</p>
<ol>
<li>Define a <b>PositionNormalTextured</b> vertex array to hold the data for the four corners of each cube face and texture information.
</li><li>Load the texture for each cube face from a file. </li><li>Setup the <b>Vertex</b> buffer for each face. </li><li>On each <b>Render</b> loop readjust the skybox. </li><li>On each <b>Render</b> loop disable Z-buffering. </li><li>On each <b>Render</b> loop use the <b>Camera</b> object passed in to determine the direction the camera is facing and draw the appropriate face.
</li><li>On each <b>Render</b> loop turn Z-buffering back on. </li></ol>
<p>If you look at the <b>RenderFace </b>method of the <b>SkyBox</b> class, you will notice that it is identical to the code we used to draw the triangle and cube in the last article.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetStreamSource ( 0, faceVertexBuffer, 0 );<br>_device.VertexFormat = CustomVertex.PositionNormalTextured.Format;<br>_device.SetTexture ( 0, faceTexture );<br>_device.DrawPrimitives ( PrimitiveType.TriangleStrip, 0, 2 );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetStreamSource(0, faceVertexBuffer, 0)<br>_device.VertexFormat = CustomVertex.PositionNormalTextured.Format<br>_device.SetTexture(0, faceTexture)<br>_device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h5>Camera Class</h5>
<p>The other major refactoring I did for this article is to move all the camera-related code into the
<b>Camera</b> class. The fixed values such as FoV and aspect ratio used in the <b>
Perspective</b> matrix are set as internal properties with the appropriate default values. I have also added methods that allow the camera to be moved left or right and up or down, and a method that moves the position of the camera. Why I added these methods
 will become clear once we integrate user input later in the article. </p>
<p>Now that all of the graphics for the game except the enemy units are done, let's get the tank moving so we can explore our new world.
</p>
<h5>Controlling Input</h5>
<p>Controlling input devices is not nearly as cool as graphics manipulation or artificial intelligence, but without it you couldn't have a game. Reacting to user input allows the user to move around in and manipulate the 3D world we have created.
</p>
<p>The DirectInput API allows you to control the mouse, keyboard, joystick, game-pad, or force feedback device. Some games also provide the ability for voice input to control the game, but that is beyond the scope of our game.
</p>
<h5>Adding DirectInput</h5>
<p>The first step when adding input support to an application is to reference the
<b>Microsoft.DirectX.DirectInput.dll</b> assembly. The next step is to add the using statement to each class in which you plan to use the DirectInput classes (unless you really like typing).
</p>
<h5>Detecting Devices</h5>
<p>A good API provides a common way to access similar devices. This is true in DirectX where physical devices such as video cards, sound cards, and input devices are abstracted into the
<b>Device</b> class. This class shields us as developers from knowing any of the hardware-specific details. In the DirectInput namespace a Device represents any of the potential input devices.
</p>
<p>Another familiar construct is the <b>Manager</b> class. We used the <b>Manager</b> class from the Direct3D namespace to get information about the adapters and to retrieve device capabilities for each adapter. In DirectInput the process is very similar.
</p>
<p>To get a list of specific devices such as all keyboards connected to the computer, you use the
<b>GetDevices</b> method of the Manager class and pass in the DeviceClass or DeviceType and one of the EnumDevicesFlags enumeration values to filter the list further. A computer can have many input devices but as a minimum it should have a keyboard and mouse.
</p>
<p><b>Note:</b> Most of the time you are going to use <b>EnumDevicesFlags.AttachedOnly</b> to get only the attached devices of a particular type.
</p>
<p>To make things a little more obscure, a mouse is considered a Pointer type in the
<b>DeviceClass</b> enumeration. You can use any combination of to retrieve a custom list of input devices.
</p>
<p>Each call to <b>GetDevices</b> returns a <b>DeviceList</b> class. This <b>DeviceList</b> in turn contains a
<b>DeviceInstance</b> structure for each device. The <b>DeviceInstance</b> structure contains the information about each device, the most important of which is the
<b>InstanceGuid</b>. This is a unique identifier for each device on our system that we need to know so we can communicate with that device.
</p>
<p><b>Note: </b>Just because a device is in the <b>DeviceList</b> does not mean that it is actually attached. You can use the
<b>InstanceGuid</b> and the <b>GetDeviceAttached</b> method to determine if the device is attached.
</p>
<p>The Manager class exposes a <b>Devices</b> property that contains a <b>DeviceList</b>.
</p>
<p>Note that the <b>DeviceInstance</b> structure is not actually a device; there is nothing we can do with it in terms of connecting to it. The only use it has is to provide a GUID which we can then use to actually connect to or acquire that device.
</p>
<h5>Connecting to a Keyboard</h5>
<p>The first device we are going to connect to is the keyboard. This is probably the most common device used to interact with games. Most modern games enable the user to control the game using the keyboard and the mouse, as there are too many actions to perform
 to use just one of these devices. Depending on your audience, you need to choose the primary input device and decide whether to offer configurable choices for secondary devices. You also need to remember that some computers, such as slate-mode Tablet PCs,
 have no keyboard, so offering alternate input means broadens your potential audience.
</p>
<p>Regardless of what input options you offer, the steps to set up any input device are the same.
</p>
<ol>
<li>Instantiate a <b>Device</b> class passing the type of device. </li><li>Set the cooperation level of the device. </li><li>Set the format of the data returned for the device. </li><li>Acquire the device. </li><li>Poll the device. </li><li>Read the state data to determine what actions the user did. </li></ol>
<p>Using good OO practices, we first create a keyboard class that will encapsulate all keyboard-specific functionality and provide a single access point for the rest of the game to any keyboard functionality.
</p>
<p>The first step is to create a <b>Device</b> object for the keyboard. We do this using the Keyboard value of the
<b>SystemGuid</b> enumeration. This lets us connect to the default keyboard. Using the default keyboard is safer than enumerating the devices and picking a specific one, because you don't know beforehand what devices all your users might have.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device = <span class="kwrd">new</span> Device ( SystemGuid.Keyboard );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device = <span class="kwrd">New</span> Device(SystemGuid.Keyboard)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The next step is to set the Cooperative level of the device. The values of the
<b>CooperativeLevelFlags</b> enumeration determine how much control we chose to take over the device and how much control we leave to other applications.
</p>
<p>The <b>CooperativeLevelFlags</b> enumeration contains five values. </p>
<ul>
<li>Exclusive </li><li>NonExclusive </li><li>Foreground </li><li>Background </li><li>NoWindowsKey </li></ul>
<p>The <b>Background</b> and <b>Foreground</b> values are mutually exclusive, as are the
<b>Exclusive</b> and <b>NonExclusive</b> values. The <b>Foreground</b> option states that we only want data from the device if the window we passed into the
<b>SetCooperativeLevel</b> method has the focus. The <b>Background</b> option simply means that we always want data from the device.
<b>Exclusive</b> means that we want priority for control of the device while <b>NonExclusive</b> means we don't. Even when using the
<b>Exclusive</b> option it is still possible to lose the device, which is why we add the reacquire logic to the
<b>Poll</b> method to ensure we can get the device back when we want to read its state. The
<b>NoWindowsKey</b> option can be combined with any of the other settings and specifies that we want to ignore the Windows logo key on the keyboard. This setting is important when running in full screen mode, because the Windows key causes the application to
 loose focus. </p>
<p>For BattleTank 2005 we combine the <b>Background </b>and <b>NonExclusive</b> values to allow other applications maximum control over this device.
</p>
<p>We also need to pass in a reference to the window we are using so DirectX knows which window's input we are interested in.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetCooperativeLevel ( form, CooperativeLevelFlags.Background | <br>    CooperativeLevelFlags.NonExclusive ); </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"></pre>
<pre class="csharpcode"></pre>
<pre class="csharpcode">_device.SetCooperativeLevel(form, CooperativeLevelFlags.Background Or _ <br>    CooperativeLevelFlags.NonExclusive)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The next step is to determine the data format we expect this device to return. We cover the contents of this data structure a little later in the article.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetDataFormat ( DeviceDataFormat.Keyboard ); </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetDataFormat(DeviceDataFormat.Keyboard)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The last step is to actually acquire the device. You can think of this like opening a communications channel to the device. Since there are lots of things that could go wrong at this point, it is best to wrap the
<b>Acquire</b> call into a try/catch block. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">try</span><br>{<br>    _device.Acquire ( );<br>}<br><span class="kwrd">catch</span> ( DirectXException ex )<br>{<br>    Console.WriteLine ( ex.Message );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Try</span><br>    _device.Acquire()<br><span class="kwrd">Catch</span> ex <span class="kwrd">As</span> DirectXException<br>    Console.WriteLine(ex.Message)<br><span class="kwrd">End</span> Try</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>After acquiring the device we can read its state, which is a byte array. The first 256 values of this array hold the state of the keyboard; the next 8, the state of the mouse; and the last 32, the state of the joystick. Setting the device data format simply
 restricts the returned array to the set of values for the specified device. The <b>
KeyboardState</b> structure, for example, only contains the first 256 bytes of the raw state.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> KeyboardState _state; </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> _state <span class="kwrd">As</span> KeyboardState</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>To get this state from the device we first call the <b>Poll</b> method. This method communicates with the actual hardware. Then we copy the state into a local data structure (the
<b>_state </b>variable). </p>
<p>Since we are going to do this on every frame, I placed this particular sequence of calls into their own public method called
<b>Poll</b>. In the game loop we then call _<code>keyboard.Poll()</code> and use the state data structure to see what keys were pressed. This is where we deal with a device which may have been acquired by another application by attempting to reacquire it.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">try</span><br>{<br>    _device.Poll ( );<br>    _state = _device.GetCurrentKeyboardState ( );<br>}<br><span class="kwrd">catch</span> ( NotAcquiredException )<br>{<br>    <span class="rem">// try to reqcquire the device</span><br>    <span class="kwrd">try</span><br>    {<br>        _device.Acquire ( );<br>    }<br>    <span class="kwrd">catch</span> ( InputException iex )<br>    {<br>        Console.WriteLine ( iex.Message );<br>        <span class="rem">// could not get the device</span><br>    }<br>}<br><span class="kwrd">catch</span> ( InputException ex2 )<br>{<br>    Console.WriteLine ( ex2.Message );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Try</span><br>    _device.Poll()<br>    _state = _device.GetCurrentKeyboardState<br><span class="kwrd">Catch</span> generatedExceptionVariable0 <span class="kwrd">As</span> NotAcquiredException<br>    <span class="kwrd">Try</span><br>        _device.Acquire()<br>    <span class="kwrd">Catch</span> iex <span class="kwrd">As</span> InputException<br>        Console.WriteLine(iex.Message)<br>    <span class="kwrd">End</span> <span class="kwrd">Try</span><br><span class="kwrd">Catch</span> ex2 <span class="kwrd">As</span> InputException<br>    Console.WriteLine(ex2.Message)<br><span class="kwrd">End</span> <span class="kwrd">Try</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The only step remaining is to examine the state data returned to see what actions the user performed.
</p>
<p>In addition to managing the device state each time we poll the device, we want to make sure to release it when we are finished using it. We accomplish this by calling the
<b>Unacquire</b> method of the device in the <b>Dispose</b> method. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( _device != <span class="kwrd">null</span> )<br>    _device.Unacquire ( );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> <span class="kwrd">Not</span> (_device <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">Then</span><br>    _device.Unacquire()<br><span class="kwrd">End</span> If</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h5>Connecting to a Mouse</h5>
<p>Connecting to a mouse is almost identical to connecting to a keyboard. The differences are the
<b>SystemGuid</b> passed to the <b>Device</b> constructor, the <b>DeviceDataFormat</b>, the data structure used to store the state information, and the method call used to retrieve the device state.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device = <span class="kwrd">new</span> Device ( SystemGuid.Mouse );<br>_device.SetDataFormat ( DeviceDataFormat.Mouse );<br><span class="kwrd">private</span> MouseState _state;<br><span class="kwrd">public</span> <span class="kwrd">void</span> Poll ( )<br>{<br>    _device.Poll ( );<br>    _state = _device.CurrentMouseState;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device = <span class="kwrd">New</span> Device(SystemGuid.Mouse)<br>_device.SetDataFormat(DeviceDataFormat.Mouse)<br><span class="kwrd">Private</span> _state <span class="kwrd">As</span> MouseState<br><span class="kwrd">Public</span> <span class="kwrd">Sub</span> Poll()<br>        _device.Poll()<br>        _state = _device.CurrentMouseState<br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Using the mouse also provides the ability to define how the X, Y and Z (No, don't pick up your mouse, the Z value is the value for the mouse scroll wheel on certain mice) values are reported on each poll. Setting the
<b>AxisModeAbsolute</b> value to true returns the coordinates in screen coordinates, while setting this value to false returns the change in pixels from the previous poll. We set this value as soon as we have acquired the device.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.Acquire ( );<br>_device.Properties.AxisModeAbsolute = <span class="kwrd">false</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.Acquire()<br>_device.Properties.AxisModeAbsolute = <span class="kwrd">False</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Using the false option is valuable if you want to determine the speed in which the user moved the mouse using the time elapsed between polls and the distance traveled in that time frame while the first option is more valuable if the user is selecting something
 from the screen. </p>
<h5>Connecting to a Joystick</h5>
<p>Connecting to a joystick follows the same general steps as for the keyboard and mouse, but, since there is no such thing as a default joystick, no corresponding
<b>SystemGuid</b> value exists. Instead, we need to use the <b>GetDevices</b> method of the
<b>Manager</b> class, passing in <b>GameControl</b> type for the <b>DeviceClass</b> and
<b>AttachedOnly</b> for the <b>EnumDevicesFlags</b> to enumerate any attached joysticks. You would probably want to present some type of UI to the user to let them choose from a list of devices found or you could just use the first device as the code snippet
 does. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">DeviceList gameControllerList = <br>    Manager.GetDevices(<br>        DeviceClass.GameControl, <br>        EnumDevicesFlags.AttachedOnly);<br><br><span class="kwrd">if</span> (gameControllerList.Count &gt; 0)<br>{<br>    <span class="kwrd">foreach</span> (DeviceInstance deviceInstance <span class="kwrd">in</span> gameControllerList)<br>    {<br>        _device = <span class="kwrd">new</span> Device(deviceInstance.InstanceGuid);<br>        _device.SetCooperativeLevel(form,<br>            CooperativeLevelFlags.Background | <br>            CooperativeLevelFlags.NonExclusive);<br>        <span class="kwrd">break</span>;<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">Dim</span> gameControllerList <span class="kwrd">As</span> DeviceList<br>gameControllerList = Manager.GetDevices(DeviceClass.GameControl, _<br>    EnumDevicesFlags.AttachedOnly)<br><span class="kwrd">If</span> (gameControllerList.Count &gt; 0) <span class="kwrd">Then</span><br>    <span class="kwrd">Dim</span> deviceInstance <span class="kwrd">As</span> DeviceInstance<br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> deviceInstance <span class="kwrd">In</span> gameControllerList<br>        _device = <span class="kwrd">New</span> Device(deviceInstance.InstanceGuid)<br>        _device.SetCooperativeLevel(Form, CooperativeLevelFlags.Background <br>        <span class="kwrd">Or</span> CooperativeLevelFlags.NonExclusive)<br>        Break()<br>    <span class="kwrd">Next</span><br><span class="kwrd">End</span> If</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The next step is to specify a new <b>DeviceDataFormat</b> and new type for the _<b>state</b> data structure. Finally you need to retrieve the joystick state from the device inside the
<b>Poll</b> method. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetDataFormat ( DeviceDataFormat.Joystick );<br><span class="kwrd">private</span> JoystickState _state;<br><span class="kwrd">public</span> <span class="kwrd">void</span> Poll ( )<br>{<br>    _device.Poll ( );<br>    _state = _device.CurrentJoystickState;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_device.SetDataFormat(DeviceDataFormat. Joystick)<br><span class="kwrd">Private</span> _state <span class="kwrd">As</span> JoystickState<br><span class="kwrd">Public</span> <span class="kwrd">Sub</span> Poll()<br>        _device.Poll()<br>        _state = _device.CurrentJoystickState<br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In BattleTank 2005 we are not going to use a joystick, but feel free to add this capability on your own if you have a joystick. If you own a force-feedback device you might also want to experiment with using it in the game.
</p>
<p>Now that we have access to the various forms of input devices, and know how to retrieve their state we need to know how to read the various state data structures to determine user actions.
</p>
<h5>Determining User Actions</h5>
<p>Each of the data structures for the state are byte arrays. The <b>KeyboardState</b> is a byte array 256 bytes long. Each byte represents the state of a key on the keyboard and the position in the array matches the value of the
<b>Key</b> enumeration. The indexer for the <b>KeyboardState</b> returns a Boolean value for each index checked. For example, to see if the user pressed the Escape key you simply test that the most significant bit is set at that index location (position 1 for
 Escape) in the array. If this expression returns true then the user pressed the Escape key, otherwise it returns false.
</p>
<p>Each poll method may return values for multiple keys such as when the user pressed certain key combinations (Ctrl&#43;Alt&#43;Delete is a common one for me when I program). DirectInput supports a maximum of five key values, but you should be nice to your users and
 stick to single key actions if possible. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_state[Key.Escape] </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<p>&nbsp;</p>
<pre class="csharpcode"></pre>
<pre class="csharpcode">_keyboard.State(Key.Escape)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <b>MouseState</b> is a structure that provides three public properties for the X, Y and Z values, as well an eight byte long array for the state of the mouse buttons that is retrieved by calling the
<b>GetMouseButtons</b> method. </p>
<p>Checking for the button information is the same for the mouse buttons as it was for the keyboard keys. You simply check the most significant bit at each position to determine if the corresponding button was pressed.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( 0 != mouseButtons[0])<br>    Console.WriteLine ( <span class="str">&quot;Primary Button pressed&quot;</span> );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> <span class="kwrd">Not</span> (0 = _mouse.MouseButtons(0)) <span class="kwrd">Then</span><br>    Console.WriteLine(<span class="str">&quot;Fire!&quot;</span>)<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The 0 position represents the primary button which could be the left or right mouse button depending on how the user configured the mouse.
</p>
<p>Depending on the <b>AxisModeAbsolute</b> setting, the X, Y and Z values return the absolute or relative position of the mouse. Regardless of this setting the values for the X axis are always positive to the right and negative to the left, positive forward
 and negative backward for the Y value, and positive when spinning the scroll wheel forward and negative backward for the Z value.
</p>
<h5>Reacting to User Action</h5>
<p>Now that we can detect what the user is doing, it is time to take that input and use it to manipulate our world. First we create a method called
<b>CheckForInput</b> that will contain all of the input-related code. (In a later article I will show you why this is not the best way of tracking and reacting to user input and how a system called Action Mapping can be used to reduce the amount of code and
 avoid code duplication.) For right now we are going to set up BattleTank 2005 to use the cursor keys to change the heading and pitch of the camera (move it up/down and left/right). Note that this does not change the location of the camera. The first step is
 to poll the devices to retrieve the latest state information. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_keyboard.Poll ( );<br>_mouse.Poll ( );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">_keyboard.Poll()<br>_mouse.Poll()</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Then we test the state for the keys we are interested in and react accordingly.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( _keyboard.State[Key.LeftArrow] )<br>    _camera.MoveCameraLeftRight ( -0.5f );<br><br><span class="kwrd">if</span> ( _keyboard.State[Key.RightArrow] )<br>    _camera.MoveCameraLeftRight ( 0.5f );<br><br><span class="kwrd">if</span> ( _keyboard.State[Key.UpArrow] )<br>    _camera.MoveCameraUpDown ( -0.5f );<br><br><span class="kwrd">if</span> ( _keyboard.State[Key.DownArrow] )<br>    _camera.MoveCameraUpDown ( 0.5f );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> _keyboard.State(Key.LeftArrow) <span class="kwrd">Then</span><br>    _camera.MoveCameraLeftRight(-0.5F)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> _keyboard.State(Key.RightArrow) <span class="kwrd">Then</span><br>    _camera.MoveCameraLeftRight(0.5F)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> _keyboard.State(Key.UpArrow) <span class="kwrd">Then</span><br>    _camera.MoveCameraUpDown(-0.5F)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> _keyboard.State(Key.DownArrow) <span class="kwrd">Then</span><br>    _camera.MoveCameraUpDown(0.5F)<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We also want to use the mouse to move the camera, so we add another set of checks for the mouse input.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( 0 != ( _mouse.State.X | _mouse.State.Y ) )<br>{<br>    _camera.MoveCameraLeftRight ( _mouse.State.X / 10 );<br>    _camera.MoveCameraUpDown ( _mouse.State.Y / 10 );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> <span class="kwrd">Not</span> (0 = (_mouse.State.X <span class="kwrd">Or</span> _mouse.State.Y)) <span class="kwrd">Then</span><br>    _camera.MoveCameraLeftRight(_mouse.State.X / 10)<br>    _camera.MoveCameraUpDown(_mouse.State.Y / 10)<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can adjust the increments used in the <b>MoveCameraLeftRight</b> and <b>MoveCameraUpDown</b> methods to make the movement slower or faster.
</p>
<p>The final step is to add a key that enables us to exit the application. The Escape key is the natural choice:
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( _keyboard.State[Key.Escape] )<br>{<br>    Application.Exit ( );<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> _keyboard.State(Key.Escape) <span class="kwrd">Then</span><br>    Application.<span class="kwrd">Exit</span>()<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In addition to moving the camera around, we also want to move the location of the camera since that is how we are going to simulate driving around in our tank. The only problem is that, with no fixed items in the world, we can't really tell when we have
 moved, since the only reference point is the skybox, which never changes position. To overcome this limitation until we add units in the next article, I am simply writing out the new camera location to the Console whenever it changes.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( _keyboard.State[Key.W] )<br>    _camera.MoveCameraPosition ( 10, 0, 0 );<br><br><span class="kwrd">if</span> ( _keyboard.State[Key.S] )<br>    _camera.MoveCameraPosition ( -10, 0, 0 );<br><br><span class="kwrd">if</span> ( _keyboard.State[Key.A] )<br>    _camera.MoveCameraPosition ( 0, 10, 0 );<br><br><span class="kwrd">if</span> ( _keyboard.State[Key.D] )<br>    _camera.MoveCameraPosition ( 0, -10, 0 );<br><br><span class="kwrd">if</span> ( oldX != _camera.X )<br>{<br>    Console.WriteLine ( _camera.X &#43; <span class="str">&quot;, &quot;</span> &#43; _camera.Y );<br>    oldX = _camera.X;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> _keyboard.State(Key.W) <span class="kwrd">Then</span><br>    _camera.MoveCameraPosition(10, 0, 0)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> _keyboard.State(Key.S) <span class="kwrd">Then</span><br>    _camera.MoveCameraPosition(-10, 0, 0)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> _keyboard.State(Key.A) <span class="kwrd">Then</span><br>    _camera.MoveCameraPosition(0, 10, 0)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> _keyboard.State(Key.D) <span class="kwrd">Then</span><br>    _camera.MoveCameraPosition(0, -10, 0)<br><span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">If</span> <span class="kwrd">Not</span> (oldX = _camera.X) <span class="kwrd">Then</span><br>    Console.WriteLine(_camera.X &amp; <span class="str">&quot;, &quot;</span> &amp; _camera.Y)<br>    oldX = _camera.X<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The last piece of input-checking we need to add is checking the mouse buttons. For right now, let's assume that the default button on the mouse causes the tank to fire. We are going to add more exciting action later on, but all we can do now is to write
 &quot;Fire!&quot; to the Console. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">if</span> ( 0 != _mouse.MouseButtons[0] )<br>    Console.WriteLine ( <span class="str">&quot;Fire!&quot;</span> );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">If</span> <span class="kwrd">Not</span> (0 = _mouse.MouseButtons(0)) <span class="kwrd">Then</span><br>    Console.WriteLine(<span class="str">&quot;Fire!&quot;</span>)<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>That's it for input. As I mentioned before, there are better ways of relating keyboard and mouse keys and movement to actions in the game. You may also notice that when moving the camera, sometimes a single button click causes two movements. This is due
 to the fact that the game loop is faster than we are and the key is pressed long enough to be picked up in two game loops. We are also going to fix that in the next article.
</p>
<h4>Summary</h4>
<p>Once again I find myself running out of space before being able to cover all of the items I wanted, but I hope there is enough stuff here to let you experiment on your own. We are going to continuously refine the game in each iteration rather than trying
 to get it perfect the first time; that is the sprit of Agile development. The important things to remember are how to use the Device class to acquire and then poll an input device, and how to determine the input from the State objects.
</p>
<p>Even though we are now able to maneuver through the 3D world, it is not very exciting, since other than the skybox there are no other items in our world. In the next article we are going to fix that by adding units, both stationary and mobile, and work on
 collision detection. We are also going to refine the camera to help us in reducing the number of items we need to render by tacking the frustum. Oh—yes, I do know that the targeting crosshairs are gone; they will be back in the next article in the form of
 a real Heads-Up-Display (HUD) class. </p>
<p>Until then: Happy coding. </p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:72ac796ea5bf46abb4ac9e7600d9662b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-IV-DirectInput</comments>
      <itunes:summary>



&amp;nbsp;
This is Part 4 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers the input device portion of DirectX, called DirectInput.



Derek Pierson
3Leaf Development

Difficulty: Intermediate
Time Required: 
3-6 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions,
DirectX SDK
Hardware: None
Download: 

C# Download
VB Download






Beginning Game Development Series


Beginning Game Development Part 1 - Introduction

Beginning Game Development Part II - Introduction to DirectX

Beginning Game Development: Part III - DirectX II

Beginning Game Development: Part IV - DirectInput

Beginning Game Development: Part V - Adding Units


Beginning Game Development: Part VI - Lights, Materials and Terrain

Beginning Game Development: Part VII –Terrain and Collision Detection

Beginning Game Development: Part VIII - DirectSound


Beginning Game Development: Part VIII - DirectSound II




Beginning Game Development: Part VIII - DirectSound III



Welcome to the fourth article on beginning game development. In this article we are going to cover the input device portion of DirectX, called DirectInput. Using DirectInput you can control joysticks, a mouse or the keyboard.
 
Before we start I need to cover a couple of items that were brought to my attention via feedback from the readers (thank you everyone for taking the time to do this) and changes not directly related to the items covered in this article.
 
Code Cleanup
To make adding the code for this section easier and to make the code more reusable I have moved some of the code from the
GameEngine class into separate classes such as Camera. Encapsulating the camera functionality in a separate object makes the code easer to change and to read. The following changes have already been integrated into the code for this article.
 

I moved the FrameworkTimer class out of the DirectX support code into a class called
HiResTimer and removed t</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-IV-DirectInput</link>
      <pubDate>Fri, 03 Nov 2006 06:51:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-IV-DirectInput</guid>      
      <dc:creator>Derek Pierson</dc:creator>
      <itunes:author>Derek Pierson</itunes:author>
      <slash:comments>23</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-IV-DirectInput/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Beginning Game Development: Part III - DirectX II</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This is Part 3 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers more advanced DirectX principles such as transforms, matrices, culling
 and clipping.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Derek Pierson</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a>,
<a href="http://www.microsoft.com/windows/directx/default.mspx">DirectX SDK</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">None</span></div>
<div class="entry_details"><b>Download: </b></div>
<div class="entry_details">
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/940729/C4FBegDev3CS.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/940729/C4FBegDev3VB.msi">VB Download</a></li></ul>
</div>
<div class="entry_details"><strong>Beginning Game Development Series</strong></div>
<ol>
<li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx">Beginning Game Development Part 1 - Introduction</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940223.aspx">Beginning Game Development Part II - Introduction to DirectX</a></div>
</li><li>
<div class="entry_details"><a class="" title="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx " href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx">Beginning Game Development: Part III - DirectX II</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940908.aspx">Beginning Game Development: Part IV - DirectInput</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx">Beginning Game Development: Part V - Adding Units</a>
</div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044115.aspx">Beginning Game Development: Part VI - Lights, Materials and Terrain</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044454.aspx">Beginning Game Development: Part VII –Terrain and Collision Detection</a></div>
</li><li>
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx">Beginning Game Development: Part VIII - DirectSound</a></div>
</li><li>
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2007/11/02/5849691.aspx">Beginning Game Development: Part VIII - DirectSound II</a></div>
</div>
</li><li>
<div class="entry_details">
<div class="entry_details">
<div class="entry_details"><a class="" href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7020067.aspx">Beginning Game Development: Part VIII - DirectSound III</a></div>
</div>
</div>
</li></ol>
</td>
</tr>
</tbody>
</table>
</span>
<h4>Introduction</h4>
<p>Welcome to the third article on beginning game development. In this article we are going to cover some of the more advanced DirectX principles such as transforms, matrices, culling and clipping.
</p>
<p>Before we start, I need to cover a couple of items that were brought to my attention via feedback from the readers (thank you everyone for taking the time to do this) and changes not directly related to the items covered in this article.
</p>
<h5>Code Cleanup</h5>
<p>These changes have already been integrated into the code for this article. </p>
<ol>
<li>I updated to the June 2005 version DirectX SDK. I did have an issue with the DirectX assemblies being added to the Global Assembly Cache (GAC), so if you have any build errors, update the references to: C:\Program Files\Microsoft DirectX 9.0 SDK (June 2005)\Developer
 Runtime\x86\DirectX for Managed Code. </li><li>In the last article you surrounded the IsWindowed setting for the PresentParameters with a
<code>#if DEBUG</code> statement. To enable this option you must go to the Project settings and enable it:
<ul>
<li>Right-click the BattleTank2005 project and select Properties. </li><li>Select the Build tab. </li><li>In the general section, check the Define DEBUG constant option. </li></ul>
</li><li>Change the color in the <b>device.Clear</b> method call from DarkBlue to Black.
</li><li>Add the following code at the very end of the GameEngine constructor to make the form a more standard size.
</li></ol>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">// force the window to a standard size</span>
<span class="rem">// the provides the correct aspect ratio of 1.33</span>
<span class="kwrd">this</span>.Size = <span class="kwrd">new</span> Size ( 800, 600 );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">'force the window to a standard size</span>
<span class="rem">' the provides the correct aspect ratio of 1.33</span>
<span class="kwrd">Me</span>.Size = <span class="kwrd">New</span> Size(800, 600)<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<ol start="5">
<li>Change the Startup position of the form to CenterScreen.
<ul>
<li>Right-click the <b>GameEngine</b> form and select <b>View Designer.</b> </li><li>In Properties, change the <b>StartPosition</b> property to <b>CenterScreen</b></li></ul>
</li></ol>
<p>Now we can actually draw something on the screen and start creating the game. </p>
<h4>Drawing the targeting crosshairs.</h4>
<p>In BattleTank 2005 we are sitting inside of a tank and looking through the targeting scope at the world around us. We use the targeting crosshairs to make it easier to hit and destroy the enemy. In real life the crosshairs are fixed in the optics of the
 cannon, so they are always visible and located in the same spot when looking through the targeting scope as a Heads-up Display (HUD).
</p>
<p>In our game we have two choices when drawing the crosshairs. </p>
<ol>
<li>Draw them directly onto the center of the screen using screen coordinates. </li><li>Draw them using world coordinates and ensure that the view point is located such that they are visible and centered on the screen.
</li></ol>
<p>The tradeoff here is between speed and extensibility. If we choose the first option we do not have to transform the coordinates, since they are already in screen coordinates, which is faster. In effect, we are removing the targeting crosshairs from the model
 space we are creating. The downside is that if we chose to change the game later on and allow the player to leave the tank, the crosshairs would also be visible when they walk around. The second option requires the coordinates to be adjusted and transformed,
 but provides us with the ultimate flexibility to change the game later on. </p>
<p>I am going to use option 2 because it is the most flexible and I am not going to waste time trying to optimize the game for speed before knowing that it is slow. When you write a game you will be faced with design choices like this and you have to understand
 the tradeoffs you are making. </p>
<p>Before we move on, let's define a model that will make it easier to describe and (we hope) understand the terms we are going to cover in this article.
</p>
<h5>A Model</h5>
<p>Imagine an empty room. I determine where in the room the X, Y, Z origin is located. In this example let's say that the front left corner of the room is the origin in this world. This room becomes my
<b>World Space.</b> (A real world space is infinite, but for now we can make do with the finite space of the room.)
</p>
<p><b>World Space:</b> An infinite three-dimensional Cartesian space. You place your objects anywhere you want in this world to create the environment you want.
</p>
<p>Now I place a chair in the room at a predefined location. Each point on the chair can be accurately described using a set of Cartesian coordinates (X, Y, Z) and optional information about each point such as color (Color) and texture (Tu, Tv). If you think
 back to the last article you will notice that this makes each point a vertex. Since we have lots of separate vertices, we store all of them in a vertex array. When this array is loaded into memory it becomes a
<i>vertex buffer</i>. </p>
<h5>Vertex buffer</h5>
<p>Vertex buffers are ideally suited for the complex transformations that DirectX needs to perform. DirectX provides a number of predefined vertex types representing the most common vertex formats. These types are defined as structures in the
<b>CustomVertex</b> class. </p>
<p>We are going to use the <b>PositionColored</b> vertex for the targeting crosshairs. This vertex provides X, Y, Z properties and a
<b>Color</b> property, which is exactly what we need. This vertex also defines the coordinates' world space rather than screen space, which is what we decided to do.
</p>
<p>Add the following methods to the <b>GameEngine</b> class after the OnPaint method.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> CustomVertex.PositionColored[] CreateCrossHairVertexArrayTop ( )<br>{ <br>    CustomVertex.PositionColored[] crossHairs = <br>        <span class="kwrd">new</span> CustomVertex.PositionColored[7];<br>    <span class="kwrd">float</span> zval = 0f;<br>    <br>    <span class="rem">// top of targeting crosshairs</span>
    crossHairs[0].Position = <span class="kwrd">new</span> Vector3 ( -1f, 1f, zval );<br>    crossHairs[1].Position = <span class="kwrd">new</span> Vector3 ( -1f, 2f, zval );<br>    crossHairs[2].Position = <span class="kwrd">new</span> Vector3 ( 0f, 2f, zval );<br>    crossHairs[3].Position = <span class="kwrd">new</span> Vector3 ( 0f, 3f, zval );<br>    crossHairs[4].Position = <span class="kwrd">new</span> Vector3 ( 0f, 2f, zval );<br>    crossHairs[5].Position = <span class="kwrd">new</span> Vector3 ( 1f, 2f, zval );<br>    crossHairs[6].Position = <span class="kwrd">new</span> Vector3 ( 1f, 1f, zval );<br>    <br>    crossHairs[0].Color = Color.Green.ToArgb ( );<br>    crossHairs[1].Color = Color.Green.ToArgb ( );<br>    crossHairs[2].Color = Color.Green.ToArgb ( );<br>    crossHairs[3].Color = Color.Green.ToArgb ( );<br>    crossHairs[4].Color = Color.Green.ToArgb ( );<br>    crossHairs[5].Color = Color.Green.ToArgb ( );<br>    crossHairs[6].Color = Color.Green.ToArgb ( );<br>        <br>    <span class="kwrd">return</span> crossHairs;<br>}<br>    <br><span class="kwrd">private</span> CustomVertex.PositionColored[] CreateCrossHairVertexArrayBottom ()<br>{<br>    CustomVertex.PositionColored[] crossHairs = <br>        <span class="kwrd">new</span> CustomVertex.PositionColored[7];<br>    <br>    <span class="rem">// bottom of targeting crosshairs</span>
    <span class="kwrd">float</span> zval = 0f;<br>    <br>    <span class="rem">// bottom of targeting crosshairs</span>
    crossHairs[0].Position = <span class="kwrd">new</span> Vector3 ( 1f, -1f, zval );<br>    crossHairs[1].Position = <span class="kwrd">new</span> Vector3 ( 1f, -2f, zval );<br>    crossHairs[2].Position = <span class="kwrd">new</span> Vector3 ( 0f, -2f, zval );<br>    crossHairs[3].Position = <span class="kwrd">new</span> Vector3 ( 0f, -3f, zval );<br>    crossHairs[4].Position = <span class="kwrd">new</span> Vector3 ( 0f, -2f, zval );<br>    crossHairs[5].Position = <span class="kwrd">new</span> Vector3 ( -1f, -2f, zval );<br>    crossHairs[6].Position = <span class="kwrd">new</span> Vector3 ( -1f, -1f, zval );<br>    <br>    crossHairs[0].Color = Color.Green.ToArgb ( );<br>    crossHairs[1].Color = Color.Green.ToArgb ( );<br>    crossHairs[2].Color = Color.Green.ToArgb ( );<br>    crossHairs[3].Color = Color.Green.ToArgb ( );<br>    crossHairs[4].Color = Color.Green.ToArgb ( );<br>    crossHairs[5].Color = Color.Green.ToArgb ( );<br>    crossHairs[6].Color = Color.Green.ToArgb ( );<br>    <br>    <span class="kwrd">return</span> crossHairs;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Function</span> CreateCrossHairVertexArrayTop() <span class="kwrd">As</span> _<br>        CustomVertex.PositionColored()<br>    <span class="kwrd">Dim</span> crossHairs(7) <span class="kwrd">As</span> CustomVertex.PositionColored<br>    <span class="kwrd">Dim</span> zval <span class="kwrd">As</span> <span class="kwrd">Single</span> = 0.0F<br>    <span class="rem">' top of targeting crosshairs</span>
    crossHairs(0).Position = <span class="kwrd">New</span> Vector3(-1.0F, 1.0F, zval)<br>    crossHairs(1).Position = <span class="kwrd">New</span> Vector3(-1.0F, 2.0F, zval)<br>    crossHairs(2).Position = <span class="kwrd">New</span> Vector3(0.0F, 2.0F, zval)<br>    crossHairs(3).Position = <span class="kwrd">New</span> Vector3(0.0F, 3.0F, zval)<br>    crossHairs(4).Position = <span class="kwrd">New</span> Vector3(0.0F, 2.0F, zval)<br>    crossHairs(5).Position = <span class="kwrd">New</span> Vector3(1.0F, 2.0F, zval)<br>    crossHairs(6).Position = <span class="kwrd">New</span> Vector3(1.0F, 1.0F, zval)<br><br>    crossHairs(0).Color = Color.Green.ToArgb()<br>    crossHairs(1).Color = Color.Green.ToArgb()<br>    crossHairs(2).Color = Color.Green.ToArgb()<br>    crossHairs(3).Color = Color.Green.ToArgb()<br>    crossHairs(4).Color = Color.Green.ToArgb()<br>    crossHairs(5).Color = Color.Green.ToArgb()<br>    crossHairs(6).Color = Color.Green.ToArgb()<br><br>    <span class="kwrd">Return</span> crossHairs<br><span class="kwrd">End</span> <span class="kwrd">Function</span>
<span class="kwrd">Private</span> <span class="kwrd">Function</span> CreateCrossHairVertexArrayBottom() <span class="kwrd">As</span> _<br>        CustomVertex.PositionColored()<br>    <span class="kwrd">Dim</span> crossHairs(7) <span class="kwrd">As</span> CustomVertex.PositionColored<br><br>    <span class="rem">' bottom of targeting crosshairs</span>
    <span class="kwrd">Dim</span> zval <span class="kwrd">As</span> <span class="kwrd">Single</span> = 0.0F<br><br>    <span class="rem">' bottom of targeting crosshairs</span>
    crossHairs(0).Position = <span class="kwrd">New</span> Vector3(1.0F, -1.0F, zval)<br>    crossHairs(1).Position = <span class="kwrd">New</span> Vector3(1.0F, -2.0F, zval)<br>    crossHairs(2).Position = <span class="kwrd">New</span> Vector3(0.0F, -2.0F, zval)<br>    crossHairs(3).Position = <span class="kwrd">New</span> Vector3(0.0F, -3.0F, zval)<br>    crossHairs(4).Position = <span class="kwrd">New</span> Vector3(0.0F, -2.0F, zval)<br>    crossHairs(5).Position = <span class="kwrd">New</span> Vector3(-1.0F, -2.0F, zval)<br>    crossHairs(6).Position = <span class="kwrd">New</span> Vector3(-1.0F, -1.0F, zval)<br><br>    crossHairs(0).Color = Color.Green.ToArgb()<br>    crossHairs(1).Color = Color.Green.ToArgb()<br>    crossHairs(2).Color = Color.Green.ToArgb()<br>    crossHairs(3).Color = Color.Green.ToArgb()<br>    crossHairs(4).Color = Color.Green.ToArgb()<br>    crossHairs(5).Color = Color.Green.ToArgb()<br>    crossHairs(6).Color = Color.Green.ToArgb()<br><br>    <span class="kwrd">Return</span> crossHairs<br><span class="kwrd">End</span> Function</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Remember that the coordinates for the <b>Position</b> property of each vertex are defined in world space coordinates. We will transform them to screen coordinates in a while. Also note that you must call the
<b>ToArgb</b> method to convert <b>Color</b> to the 32-bit integer format required by DirectX.
</p>
<p>Before we continue we need to let the device know which type of vertex we chose. We accomplish this by setting the
<b>VertexFormat</b> property of the <b>Device</b> class to the <b>Format</b> property of the vertex we used. This property determines the
<i>fixed function pipeline</i> the device will use. Don't worry what exactly that is for right now; you just need to know that we are using the
<i>position</i> <i>and</i> <i>colored</i> pipeline. </p>
<p>In the <b>OnPaint</b> method, immediately following the <b>device.Clear</b> method add the following code.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.VertexFormat = CustomVertex.PositionColored.Format;<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.VertexFormat = CustomVertex.PositionColored.Format</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>With the crosshairs defined, we must now tell the device to actually render the object described in the vertex buffer to the screen. This is accomplished using the
<b>DrawUserPrimitives</b> method of the device class. So what are Primitives? </p>
<h5>Drawing Primitives</h5>
<p>Drawing Primitives are collections of vertices that define a single three-dimensional object. There are six primitives in DirectX listed in the
<b>PrimitiveType</b> enumeration. </p>
<ol>
<li><b>Line List:</b> Mainly used for adding Heads-up Display (HUD) information to a screen. The primitive count is equal to the number of points divided by two. The number of points must be even for this type to work.
</li><li><b>Line Strip:</b> This has the same uses as the Line List but renders a single continuous line. The primitive count is equal the number of vertices minus 1.
</li><li><b>Point List:</b> Mainly used for rendering individual points in particle images such as explosions or stars in the night sky. The primitive count is equal to the number of points in the vertex buffer.
</li><li><b>Triangle Fan:</b> This is most useful when drawing an oval object. </li><li><b>Triangle List:</b> This is the most commonly used primitive. The primitive count is the number of vertices divided by three,
</li><li><b>Triangle Strip:</b> These are most useful when rendering rectangular objects.
</li></ol>
<p>In our case we choose the <b>LineStrip</b> type to draw the crosshairs to the screen since it is an HUD. In the
<b>OnPaint</b> method, immediately following the <b>device.Clear</b> method add the following code.
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode">device.DrawUserPrimitives ( PrimitiveType.LineStrip, 6, <br>    CreateCrossHairVertexArrayTop ( ) );<br>device.DrawUserPrimitives ( PrimitiveType.LineStrip, 6, <br>    CreateCrossHairVertexArrayBottom ( ) );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.DrawUserPrimitives(PrimitiveType.LineStrip, 6, _<br>    CreateCrossHairVertexArrayTop())<br>device.DrawUserPrimitives(PrimitiveType.LineStrip, 6, _<br>    CreateCrossHairVertexArrayBottom())</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <b>DrawUserPrimitives</b> method requires us to pass in the <b>PrimitiveType</b>, the count of primitives to render, and the source of the vertex data for the object. Since we are using the
<b>LineStrip</b> primitive, the seven points in each vertex buffer create six lines.
</p>
<p>Up to this point we have not actually drawn anything to the screen, just cleared the device; so we need to tell the device that we are planning to do so. This is accomplished with the
<b>BeginScene</b> method of the device class. </p>
<h5>Begin Scene/End Scene</h5>
<p>As I mentioned in the first article, there are a lot of correlations between movies and a DirectX game. The first we encountered was frame. Now we are going to add Scenes and little later a camera.
</p>
<p>We use the <b>BeginScene</b> and <b>EndScene</b> methods of the device to define the starting and ending points of a scene. The
<b>BeginScene</b> method prepares the device for the actions that follow by locking the back buffer. The
<b>EndScene</b> method tells the device that we are finished drawing and unlocks the back buffer. You must always call
<b>EndScene</b> after calling <b>BeginScene</b> otherwise the back buffer will remain locked. The
<b>BeginScene</b> and <b>EndScene</b> methods work closely together with the <b>Present</b> method to mange the back buffer; if one of these method calls fails the others will fail also.
</p>
<p>In the <b>OnPaint</b> method of the <b>GameEngine</b> class, add calls to <b>BeginScene</b> and
<b>EndScene</b>. The call to <b>BeginScene</b> needs to occur immediately after the
<b>Clear</b> method call. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.Clear ( ClearFlags.Target, Color.Black, 1.0f, 0 );<br><span class="rem">// Tell DirectX we are about to draw something</span>
device.BeginScene ( );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.Clear(ClearFlags.Target, Color.Black, 1.0F, 0)<br><span class="rem">' Tell DirectX we are about to draw something</span>
device.BeginScene()
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>And the <b>EndScene</b> method needs to be called immediately before the <b>Present</b> method call.
</p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">// Tell DirectX that we are done drawing</span>
device.EndScene ( );
<span class="rem">// Flip the back buffer to the front</span>
device.Present ( );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">' Tell DirectX that we are done drawing</span>
device.EndScene()
<span class="rem">' Flip the back buffer to the front</span>
device.Present()
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now we are almost done. The last step remaining is to convert the world coordinates of each three-dimensional object into screen coordinates.
</p>
<p>In the last article we covered a lot of the DirectX terminology you need to understand. We are almost done with new terms, but before we can successfully render a 3-D world to the screen we need to cover one last set of definitions.
</p>
<h5>Lights, Camera, Action</h5>
<p>In our model we have described each point on the chair using Cartesian coordinates and a color value and stored these points in a vertex buffer. But DirectX still can't render the chair for me. Why? The missing pieces of information are our location in the
 room and the direction we are looking. We also need to determine how to handle the projection. Only with this information can the 3-D world be converted into the 2-D picture displayed on the screen.
</p>
<p>In DirectX our (the viewer's) location is called the camera location and it is defined by the
<i>View Matrix</i>. From now on consider the terms <i>view</i> and <i>camera</i> to be synonymous. The projection is the way distance is applied to the objects and can be compared to the lens setting of the camera.
</p>
<p>Cameras are very powerful tools in creating cool 3-D games. You can attach the camera to a moving object to get the feeling of actually being inside, or offset it slightly to the rear to get a chase view. You can also set up multiple static cameras in your
 world and view the action by switching from camera to camera. </p>
<p>All of the computations involved in converting the world coordinates to screen coordinates are performed used a
<i>Matrix</i>. These computations are called <i>Transforms</i>. Almost all of the heavy lifting performed in DirectX is the transformation of coordinates using Matrices.
</p>
<p><b>Transforms</b> (<a href="http://en.wikipedia.org/wiki/Transformation_%28mathematics%29">http://en.wikipedia.org/wiki/Transformation_%28mathematics%29</a>): Transformations change the coordinates of three-dimensional objects based on the view, projection
 type and world transform specified. These transformations are accomplished via a set of 4x4 matrices.
</p>
<p><b>Matrix</b> (<a href="http://en.wikipedia.org/wiki/Matrix_%28mathematics%29">http://en.wikipedia.org/wiki/Matrix_%28mathematics%29</a>): A rectangular table of numbers that is very efficient in transformations.
</p>
<p>You could spend a lot of time understanding the exact details of transformations with matrices. Understanding how they work is important, but you will not have to perform any manual calculations on your own, so we can skip the details for now. The
<b>Matrix</b> class contains a number of the most common methods for manipulating matrices.
</p>
<p>The first step is placing and orienting the camera in our three-dimensional world.
</p>
<h4>View Transform</h4>
<p>The view matrix defines the location of the camera and the orientation of the camera (by specifying a target). The view matrix also includes a value to determine which direction is considered to be up in our world. This is almost always the Y axis. You can
 either define your own matrix or use the built-in <b>Matrix.LookAtLH</b> and <b>
Matrix.LookAtRH</b> methods. Since we are using the left handed coordinate system we naturally use the
<b>LookAtLH</b> method (LH stands for Left Handed). Even if you do not explicitly define a view, then DirectX uses a default view.
</p>
<p>In the <b>OnPaint</b> method of the <b>GameEngine</b> class, add the following code immediately after the
<b>device.Clear</b> method call. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.Transform.View = Matrix.LookAtLH(<span class="kwrd">new</span> Vector3 (0, 0, 5f), <br>    <span class="kwrd">new</span> Vector3(0, 0, 0), <span class="kwrd">new</span> Vector3(0, 1, 0));</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.Transform.View = Matrix.LookAtLH(<span class="kwrd">New</span> Vector3(0, 0, 5.0F), _<br>    <span class="kwrd">New</span> Vector3(0, 0, 0), <span class="kwrd">New</span> Vector3(0, 1, 0))<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In Battle Tank 2005 we are placing the camera at the origin (0,0) and slightly forward on the Z axis. We then point the camera at the origin, and identify the Y axis as up by providing a value for Y.
</p>
<p>After placing and orienting the camera we need to define the projection we are going to use.
</p>
<h4>Projection Transform</h4>
<p>In DirectX there are two types of projections to choose from: </p>
<ul>
<li>Perspective (<a href="http://en.wikipedia.org/wiki/Perspective">http://en.wikipedia.org/wiki/Perspective</a>)
</li><li>Orthogonal (<a href="http://en.wikipedia.org/wiki/Orthogonal_projection">http://en.wikipedia.org/wiki/Orthogonal_projection</a>)
</li></ul>
<p>The Perspective projection is the most commonly used projection and is how humans see the world. In this projection objects appear smaller the further away from us they are and become deformed at some distance (like a road appears to converge toward the
 horizon). </p>
<p>Orthogonal projection, on the other hand, ignores distance (the Z value) so items retain their size regardless of their distance from the camera.
</p>
<p>We are going to use the Perspective Projection in BattleTank 2005. The projection determines how the vertices of the objects in the viewing frustum (<a href="http://en.wikipedia.org/wiki/Viewing_frustum">http://en.wikipedia.org/wiki/Viewing_frustum</a>)
 are transformed. The viewing frustum defines the three-dimensional space in which objects are visible to the camera. You can visualize this as a pyramid with the top cut off. The base of the pyramid is the far plane, the top the near plane, and the field of
 view is the angle at the apex. To perform this transformation we need to know four pieces of information.
</p>
<ol>
<li><b>Field of View (FoV):</b> This is typically 45 degrees or ¼ of <i>p</i> (Math.PI / 4). Reducing the FoV value is like zooming in on the scene, while a larger FoV value is like zooming out. A value greater then 45 degrees is like looking at the scene through
 a fisheye lens. </li><li><b>Aspect Ratio:</b> This is identical to the aspect ratio of your TV or Monitor and is always calculated as the viewport Width/Height. The viewport is nothing other than the form onto which we are rendering the game. Standard aspect ratios for computer
 screens are 1.33 (640x480 or 1280x1024). </li><li><b>Near Clipping Plane:</b> Objects closer to the camera than this plane are not rendered.
</li><li><b>Far Clipping Plane:</b> Objects beyond this plane are not rendered.
<p><b>Radians</b> (<a href="http://en.wikipedia.org/wiki/Radian">http://en.wikipedia.org/wiki/Radian</a>): In DirectX most angles are expressed as radians rather than degrees. To convert from degrees to radians, simple multiply the degree value by
<i>p</i>/180, where <i>n</i> is the measure of the angle in degrees. The DirectXDX library contains helper functions to perform the conversion for you in the
<b>Geometry</b> class. </p>
</li></ol>
<p>Using these values and some fancy math, DirectX transforms the vertices of each object from world coordinates to screen coordinates. To a certain extent, this transformation is what we do in our heads when we draw a picture of a three-dimensional space.
 We draw distant objects smaller, even though the actual object has not really changed its size, and we distort objects further away.
</p>
<p>In the <b>OnPaint </b>method of the <b>GameEngine </b>class, add the following code immediately after the
<b>device.Transform.View</b> method call added in the previous step. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.Transform.Projection = Matrix.PerspectiveFovLH ( (<span class="kwrd">float</span>)Math.PI / <br>    4, <span class="kwrd">this</span>.Width / <span class="kwrd">this</span>.Height, 1.0f, 100.0f);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">device.Transform.Projection = Matrix.PerspectiveFovLH ((<span class="kwrd">single</span>)Math.PI / _<br>    4, <span class="kwrd">Me</span>.Width / <span class="kwrd">Me</span>.Height, 1.0f, 100.0f)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>For BattleTank 2005 we used the traditional setting for the FoV of 45 degrees. Next we set the aspect ratio base and then define the viewing frustum as between 1 and 100 in our world coordinate space. The values for the clipping planes define the size of
 our visible world and can represent anything we want. One unit equals 10 meters in BattleTank 2005 so we have a 1 kilometer playing field.
</p>
<p>At this point you have to use some common sense when defining the viewing frustum. We could easily declare that each unit equals one kilometer, making the viewable area 100 kilometers deep. However, if we make the tanks regular size, you will never be able
 to see them beyond a couple of kilometers, so why waste resources rendering them to the screen if the player cannot see them?
</p>
<p>While the View and Projection Matrices describe the camera and camera lens, the world transformation matrix converts the model space coordinates into world space coordinates. These world space coordinates are then converted to screen coordinates in the View
 and Projection transforms. </p>
<h4>World Transform</h4>
<p>The last transform is a world transform. This transforms the object we are rendering from model space into world space.
</p>
<p>In a world transform you can move, rotate and scale each object. This transform applies to all objects drawn after setting the transform, until a new transform is specified.
</p>
<p><b>Model Space:</b> We define each object by defining each vertex with respect to the model.
</p>
<p>In BattleTank 2005 we are not going to use the World transform at this time, but I have included a transform in the code for this article that uses a test cube for you to experiment with. I suggest you play with changing the values for all three transforms
 and see how the results look on the screen. That is the easiest way to really understand what the various settings do. See the Experimenting section for details on how to do this.
</p>
<h4>Lights</h4>
<p>Whenever we draw a primitive using world coordinates, DirectX uses lighting to determine the color of each pixel. But since we have not yet defined a light source, we can simply turn the lights off at this time. If we do not turn lighting off, then DirectX
 assumes no lights are shining on the scene and renders each pixel as black. </p>
<p>In the <b>OnPaint</b> method of the <b>GameEngine </b>class, add the following code immediately after the
<b>device.Transform.Projection</b> method call added in the previous step. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">// turn off the light source</span>
device.RenderState.Lighting = <span class="kwrd">false</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">' turn off the light source</span>
device.RenderState.Lighting = <span class="kwrd">False</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In addition to controlling the lighting, the RenderState also allows us to control the culling behavior.
</p>
<h4>Culling</h4>
<p><i>Culling</i> is an operation that eliminates entire objects (unlike <i>clipping,</i> which removes only portions) from the scene that fall outside of the viewing frustum to reduce the total set of objects to render. The overall goal is of course speed;
 by eliminating the non essential objects the scene can be rendered faster. </p>
<p><b>Clipping:</b> Clipping discards portions of any single object that fall outside of the viewing frustum. Clipping is automatically managed by DirectX and requires no further intervention.
</p>
<p>When drawing a three-dimensional object, DirectX does not render the primitives (triangles) that comprise the faces of those objects that do not face the camera. This is called
<i>back face culling</i>. </p>
<p>DirectX determines which side of an object is facing the camera by using the order (winding) of the vertices. If you choose either clockwise or counterclockwise, then the vertices that are wound the opposite are on the back of the object and are culled.
 The default mode is counterclockwise culling, so you need to make sure to define your vertices in a clockwise order.
</p>
<p>The culling options are set in the <b>RenderState</b> by assigning one of the <b>
Cull</b> enumeration settings to the <b>device.RenderState.CullMode</b> property.
</p>
<p>In the <b>OnPaint </b>method of the <b>GameEngine </b>class, add the following code immediately after
<b>device.RenderState.Lighting</b> code added in the previous step. </p>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">// Turn off backface culling</span>
device.RenderState.CullMode = Cull.None;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"> <span class="rem">' Turn off backface culling</span>
device.RenderState.CullMode = Cull.None</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In the code that accompanies this article I have added a couple of extra items to make it easier for you to experiment with the various settings we just covered.
</p>
<h4>Experimenting</h4>
<p>To remove the HUD display, comment out the following lines: 122 and 123 (in VB.NET the lines are 92 and 93).
</p>
<p>You can also display a rotating cube by un-commenting lines 98, 101, 120 and commenting line 95 (VB.NET: 68, 71, 87, 90 and 65). You can change any of the values in the models or adjust the View, Projection and World transforms to see the effect of your
 changes. </p>
<p><b>Line Numbers: </b>To turn on line numbers, go to <b>Tools | Options | Text Editor | All Languages</b> and check the
<b>Line Numbers</b> box in the Display group. If you don't see the full options tree, just check the
<b>Show all Settings</b> option in the lower left of the Options dialog. </p>
<h4>Summary</h4>
<p>In these first three articles we have covered a lot of ground. The steps in the upcoming articles build upon the foundation laid in these first three articles. At this point you should know how to create a device and hook it to a Windows form and create
 a game loop using the <b>OnPaint</b> and <b>Invalidate</b> methods. You should be able to create and draw your own three-dimensional objects using vertex buffers and the
<b>DrawUserPrimitives</b> method, set up a camera, and transform the models into world space.
</p>
<p>If something is unclear at this time, you should review the links provided in the articles, the DirectX SDK, or go to one of the resources listed on the web. Once you have fully understood these principles, the rest of the game development process will be
 much easier. </p>
<p>With this knowledge you are ready to perform all but the most advanced operations in DirectX. The only steps required to add more objects to our world in BattleTank 2005 are to define them in model space, store them in a vertex buffer, and render them to
 the screen. As you imagine, complex objects consist of thousands of separate vertices, and defining them all in code is almost impossible, very error prone and extremely boring. So in the next article I will cover how to accomplish this task more efficiently.
 In the next article we are also going to finish of the last graphic pieces and then focus on controlling the tank using the classes in the DirectInput namespace.
</p>
<p>Until then: Happy coding!</p>
<span>]]&gt;</span> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:318ba75511114521905b9e7600d97270">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-III-DirectX-II</comments>
      <itunes:summary>



&amp;nbsp;
This is Part 3 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. This article covers more advanced DirectX principles such as transforms, matrices, culling
 and clipping.



Derek Pierson
3Leaf Development

Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions,
DirectX SDK
Hardware: None
Download: 


C# Download
VB Download

Beginning Game Development Series


Beginning Game Development Part 1 - Introduction

Beginning Game Development Part II - Introduction to DirectX

Beginning Game Development: Part III - DirectX II

Beginning Game Development: Part IV - DirectInput

Beginning Game Development: Part V - Adding Units


Beginning Game Development: Part VI - Lights, Materials and Terrain

Beginning Game Development: Part VII –Terrain and Collision Detection

Beginning Game Development: Part VIII - DirectSound


Beginning Game Development: Part VIII - DirectSound II




Beginning Game Development: Part VIII - DirectSound III








Introduction
Welcome to the third article on beginning game development. In this article we are going to cover some of the more advanced DirectX principles such as transforms, matrices, culling and clipping.
 
Before we start, I need to cover a couple of items that were brought to my attention via feedback from the readers (thank you everyone for taking the time to do this) and changes not directly related to the items covered in this article.
 
Code Cleanup
These changes have already been integrated into the code for this article.  

I updated to the June 2005 version DirectX SDK. I did have an issue with the DirectX assemblies being added to the Global Assembly Cache (GAC), so if you have any build errors, update the references to: C:\Program Files\Microsoft DirectX 9.0 SDK (June 2005)\Developer
 Runtime\x86\DirectX for Managed Code. In the last article you surrounded the IsWindowed setting for the PresentParam</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-III-DirectX-II</link>
      <pubDate>Fri, 03 Nov 2006 06:36:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-III-DirectX-II</guid>      
      <dc:creator>Derek Pierson</dc:creator>
      <itunes:author>Derek Pierson</itunes:author>
      <slash:comments>21</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-III-DirectX-II/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>Beginning Game Development: Part I – Introduction</title>
      <description><![CDATA[
<table cellpadding="1" cellspacing="0" border="0">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td>
<p><span class="entry_description">This is Part 1 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0.</span></p>
<p><span class="entry_description"><strong>WARNING: </strong>Managed DirectX is no longer supported.&nbsp; If you want to do 3D graphics with the .NET Framework, please use XNA (<a href="http://creators.xna.com/">http://creators.xna.com</a>)</span></p>
</td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Derek Pierson</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Basic or Visual C# Express Editions</a>,
<a href="http://www.microsoft.com/windows/directx/default.mspx">DirectX SDK</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">None</span></div>
<div class="entry_details">&nbsp;</div>
<div class="entry_details"><strong>Beginning Game Development Series</strong></div>
<ol>
<li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx">Beginning Game Development Part 1 - Introduction</a></div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940223.aspx">Beginning Game Development Part II - Introduction to DirectX</a></div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx" title="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940729.aspx">Beginning Game Development: Part III - DirectX II</a></div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/940908.aspx">Beginning Game Development: Part IV - DirectInput</a></div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/03/941679.aspx">Beginning Game Development: Part V - Adding Units</a>
</div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044115.aspx">Beginning Game Development: Part VI - Lights, Materials and Terrain</a></div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/09/1044454.aspx">Beginning Game Development: Part VII –Terrain and Collision Detection</a></div>
</li><li>
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx">Beginning Game Development: Part VIII - DirectSound</a></div>
</li><li>
<div class="entry_details">
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2007/11/02/5849691.aspx">Beginning Game Development: Part VIII - DirectSound II</a></div>
</div>
</li><li>
<div class="entry_details">
<div class="entry_details">
<div class="entry_details"><a href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7020067.aspx">Beginning Game Development: Part VIII - DirectSound III</a></div>
</div>
</div>
</li></ol>
</td>
</tr>
</tbody>
</table>
<p><b>Part I – Introduction</b> </p>
<p>Welcome to the first article of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0.
</p>
<p>This series as aimed at beginning programmers who are interested in developing a game for their own use with the .NET Framework and DirectX. The goal of this series is to have fun creating a game and learn game development and DirectX along the way. Game
 programming and DirectX have their own terms and definitions that can be difficult to understand, but after awhile, you’ll crack the code and be able to explore a new world of possibilities. I will keep things as straightforward as possible and decode terms
 as they appear. Another part of the learning curve comes from the math you’ll need to deal with DirectX. I am going to point out some resources along the way that will help you brush up on, or learn, the math skills you’ll need to keep going in DirectX.
</p>
<p>In this series, we are going to build a simple game to illustrate the various components of a commercial game. We will cover how to create great looking graphics in 3D, how to handle user input, how to add sound to a game, how to create computer opponents
 using Artificial Intelligence, and how to model real-world physics. In addition we are going to cover how to make your game playable over the network and how to optimize your game for performance. Along the way, I will show you how to apply principles of object-oriented
 development and, as well, I will share some of my experience in creating well-organized and elegant code.
</p>
<h4>Tools:</h4>
<p>Before we start writing our first game we need to talk about the tools we will use.
</p>
<p>The most important tool for any developer is the Integrated Development Environment (IDE). This is where you are going to spend the majority of your time writing and debugging code, so it needs be powerful and fast.
</p>
<p>Visual Studio 2005 (also known by the codename “Whidbey&quot;) is the third version of the standard Microsoft IDE for .NET Framework-based applications. Visual Studio 2005 introduces a number of Express versions that provide most of the functionality of their
 more advanced counterparts but are simplified for the novice, hobbyist, and student developer and cost much less (There are express versions available for VB, C#, C&#43;&#43;, J# and for Web Developers using ASP.NET). For this series, I am going to use both Visual
 C# Express and Visual Basic Express. If you have not already done so, download the C# or Visual Basic Visual Studio Express IDE at:
<a href="http://msdn.microsoft.com/express">http://msdn.microsoft.com/express</a>.
</p>
<p>The second important tool we need to create a great looking game is a graphics Application Programming Interface (API). Without such an API it would be extremely difficult to access the graphics capabilities of your PC. The API we are going use is the DirectX
 API. This API allows us to create powerful multimedia applications on the Windows platform. To work on the game, you will need to download the latest DirectX SDK at:
<a href="http://www.microsoft.com/windows/directx/default.aspx">http://www.microsoft.com/windows/directx/default.aspx</a>. Make sure that you download the SDK and not just the runtime. The SDK includes samples and other utilities that are extremely useful when
 developing using DirectX. </p>
<p>At some point in your game development experience you are going to have to create or modify graphics. Every copy of Microsoft Windows comes with Microsoft Paint, and while it is not the most powerful program, you already own it and it is good enough for
 most of our needs. </p>
<p>As we dive deeper into DirectX and cover 3D models and sounds, you might find the need to use other programs to manipulate the image or sound files. As we cover these topics I will point you towards free or inexpensive programs and resources on the Web.
</p>
<p>Finally, you need to know where to go to get help. One of the best places is &nbsp;the public newsgroups. Here, you can ask questions and get answers from people with the same interests as you. Microsoft MVPs and employees also monitor these newsgroups and provide
 help for you along the way. The newsgroups that are going to be of most interest for game programming are:
</p>
<ul>
<li>Managed DirectX: <a href="http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.win32.programmer.directx.managed&amp;lang=en&amp;cr=US">
microsoft.public.win32.programmer.directx.managed</a> </li><li>C#: <a href="http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.dotnet.languages.csharp&amp;lang=en&amp;cr=US">
microsoft.dotnet.languages.csharp</a> </li><li>VB: <a href="http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.dotnet.languages.vb&amp;lang=en&amp;cr=US">
microsoft.dotnet.languages.vb</a> </li></ul>
<p>Other places to go for inspiration and help for gaming are: </p>
<ul>
<li>The ZBuffer: <a href="http://www.thezbuffer.com/">http://www.thezbuffer.com/</a>
</li><li>GameDev.net: <a href="http://www.gamedev.net/">http://www.gamedev.net/</a> </li><li>flipCode: <a href="http://www.flipcode.com/">http://www.flipcode.com/</a> </li><li>Gamasutra: <a href="http://www.gamasutra.com/">http://www.gamasutra.com/</a> [Professional audience, but many articles from Game Developer, including tutorials]
</li></ul>
<h4>&nbsp;What makes a successful game?</h4>
<p>My first experience using a computer was in 1981 on a Sinclair ZX Spectrum. The first 5 years of my computing life were spent on nothing but writing and modifying games for the Sinclair and later the Commodore 64, but, heck, what else are you going to do
 as a teenager? While much has changed in terms of hardware capabilities and available APIs, the properties of a great game have not.
</p>
<p>Games today have become so complex that they require large numbers of developers, graphic artists, testers and managerial overhead to develop. They rival large commercial enterprise application in their complexity and cost many millions of dollars to develop
 and market. The payback, however, can be enormous and rival Hollywood blockbuster movies in sales – Halo 2 grossed $100M in its first day of availability. &nbsp;
</p>
<p>All successful games have a couple of features in common that made them stand out.
</p>
<ul>
<li>The main ingredient for a successful game is the game idea. Regardless how cool your graphics are, how good the music is, if the idea is lame no one is going to play the game.
</li><li>The second most important feature is the playability of the game. If the game is too hard then players are quickly going to get frustrated and stop playing. Conversely, if the game play is too easy then the player is going to get bored and stop playing.
 A good game provides multiple levels of difficulty that continuously challenge the player without overwhelming or boring them.
</li><li>Together, the game idea and its playability are the “game design” (not to be confused with “level design,” which is the application of the overall game design to specific segments of the game). There are certain game designers who have a golden touch. Shigeru
 Miyamoto (the creator of Donkey Kong, Zelda, and Mario) and Will Wright (Sim-everything) are two prominent examples. Miyamoto’s keynote address to the 1999 Game Developer’s Conference is available at
<a href="http://www.gamasutra.com/features/20030502/miyamoto_01.shtml">http://www.gamasutra.com/features/20030502/miyamoto_01.shtml</a> and Wright’s recent discussion of the design philosophy of Spore (<a href="http://www.gamespy.com/articles/595/595975p1.html?fromint=1">http://www.gamespy.com/articles/595/595975p1.html?fromint=1</a>)
 are good inspirations for designers of all stripes, while the book “Theory of Fun for Game Design” by Raph Koster has gotten excellent reviews in the community.
</li><li>The third ingredient to a successful game is the set of graphics. They need to be good enough to compliment the game idea and game play but not so resource intensive or flashy that they distract from it.
</li><li>The final ingredient is performance. No one wants to play a slow game. I still remember an adventure game on my Commodore64 that took 10 minutes to render each scene. I still played it, mind you, because the game idea was great and there were no other options
 around but it was irritating.&nbsp; Graphics and performance are closely related. The more fancy graphics you add to a game to slower the performance. The next biggest performance issue is the AI. A lot of game development today focuses on how to make things faster
 and not coming up with new ideas. However, when you’re learning a complex programming technique such as game programming, it’s vitally important not to optimize prematurely. An understanding of the performance pipelines, and the
<i>skills</i> to write clean code, profile it, and improve it are much more important than any single optimized function.&nbsp;&nbsp;
</li></ul>
<p>If you apply your design efforts in this order you, too, can create a great game. It may not be a refined first person shooter like Battlefield 1942, but Tetris is arguably one of the most popular games and has neither fancy 3D graphics nor Dolby digital
 sound. Even today, games like Gish (<a href="http://www.chroniclogic.com/index.htm?gish.htm">http://www.chroniclogic.com/index.htm?gish.htm</a>) demonstrate what can come from creative independent developers. If you can write enough of a game to show your
 game idea, then maybe you can interest the large gaming companies in your game. The Independent Games Festival is the “Sundance” of the game community, runs concurrently with the professional Game Developers Conference and, believe me, is among the most closely-watched
 events at the show. </p>
<h4>Our Game idea:&nbsp;</h4>
<p>Now that you know what features make a great game, the next step is to lay out the game proposal for our game.
</p>
<p><span>Idea</span>: Since coming up with a unique and creative game idea is the core of any game, I am going to cheat and use the game idea from the first 3D game I ever saw: Atari’s Battlezone. (If I had that great idea why would I let of all you know anyway?)
 Battlezone is a basic first-person shooter game in which you are looking through the viewfinder of a tank into a 3D landscape. The goal is to destroy as many of the opponent’s tanks as possible before getting destroyed yourself. The landscape includes random
 objects behind which you can hide. The game screen includes a radar to show you the location of your opponents and the current score.
</p>
<p><span>Playability</span>: The original game started out fairly slowly but kept adding more opponent tanks and other random enemies.&nbsp; The game also increased the speed and intelligence of the opponents. All of this kept the game challenging but playable.
</p>
<p><span>Graphics</span>: The original game used graphics that proved just engaging enough to feel like you were in a 3D world, but because of the hardware available in 1980 (an 8-bit processor running at 1.5
<i>mega</i>hertz) it rendered the 3D objects as wire frames. These graphics were advanced when the game first came out, but we are going to improve upon them using the magic of DirectX (and the magic of 25 years of Moore’s Law!).
</p>
<p><b>Screenshot of Atari’s Battlezone game – complete with wire frame mountains, tanks, and even a wire frame moon for added realism!</b>
</p>
<p><span>Performance</span>: This game pushed the limits of the hardware available at the time. This is evident in the use of the wire frame objects. If the game had been written to fill these objects then it would have been unplayable. With today’s advanced
 hardware we should not have any performance issues other than those introduced by us writing sloppy code.
</p>
<p>Now that we have decided on a game, the next step is to write down the goals of your game. This does not need to be anything formal but the simple act of writing things down has the tendency to make ideas clearer. At a minimum you need to determine the object
 of the game, what the player can and cannot do and how the player interacts with the game. We also should define what the scoring system is going to be like and what are the victory conditions.
</p>
<p>For our game these are the simple specification I came up with. </p>
<ul>
<li>A 3D first-person shooter game </li><li>The goal is to destroy as many enemies as possible </li><li>The player can move through the landscape on the ground just as a regular tank can. The tank can not fly, nor can it change speed.
</li><li>The game play will be controlled through the keyboard for moving and shooting. The mouse will be used to interact with the menus and start/stop the game. We will not support a joystick.
</li><li>The player will receive a score that is based on the distance at which the enemy tank was destroyed. The further the tank was, the higher the score. Each round fired reduces the score by a set amount, unless that round hits a target.
</li><li>The game will be divided into levels. Each level will have a pre-defined number of enemies. Once all enemies have been eliminated, the player advances to the next level. There is no limit to the levels.
</li></ul>
<p>Now we are ready to do some coding. In general, it is best to write down just the overall idea of the application. Spending a lot of effort upfront designing every little detail is just a waste of time. As we add more functionally to the game we will continuously
 do small design sessions to formulate our ideas. This iterative approach to developing software is the best way to create good software, and is more fun at the same time.
</p>
<h4>Creating the game Project:</h4>
<p>Now we are ready to write some code. The first step is to create a new solution in Visual Studio 2005.
</p>
<ul>
<li>Select <b>File | New | Project</b> and choose <b>Windows Application</b> from the template list. In the Name field at the bottom of the dialog, replace the default
<b>WindowsApplication1</b> with <b>BattleTank2005</b> and click <b>OK</b>. </li></ul>
<p>Visual Studio now creates a new solution for us called BattleTank2005 that contains a single project with the same name.
</p>
<p>First, we need to rename the class to something more descriptive. Naming is one of the most efficient methods of keeping code well organized and understandable. Always choose names that clearly describe what the item is doing and avoid meaningless names
 like Class1 and Form1. </p>
<ul>
<li>From the Edit menu, select Find and Replace, then select Quick Replace. Set the
<b>Find What</b> field to 'Form1', <b>Replace What</b> field to 'GameEngine' and the
<b>Look in</b> field to 'Current Project' (see Figure below). Click Replace All to make this change (there should be five changes made)
</li><li>Next <b>right-click</b> <b>Form1</b> in the <b>Solution Explorer</b> and select
<b>Rename</b>. Change Form1.cs to GameEngine.cs. </li></ul>
<p><b>Replacing Form1 text with GameEngine. You'll thank yourself later.</b> </p>
<p>Another trick to keeping things organized is to ensure that the files in the Solution Explorer are named exactly the same as the classes they contain and to always create a separate file for each distinct element such as each class or enumeration.
</p>
<p>Now we have a Windows application that we can run, but it doesn’t do anything. The form has no other controls on it such as buttons you can click or textboxes to display any information. In a regular Windows Forms application we would now add such controls
 to the forms to create our final application, but for our game we are going draw everything using the DirectX API rather than the Windows Forms API.
</p>
<p>We really only need the Form for its Windows Handle, which is basically its unique name among all the other windows on the screen. We will use this handle to set up our DirectX drawing surface. The other use of the Form is that it contains an event that
 we are going to use to create our render loop. </p>
<h4>Adding the Render loop</h4>
<p>A game is much different from a regular application, such as Microsoft Word. Word presents a screen to the user that mimics a page in a typewriter and then waits for the user to do something. This something could be pressing the keys on the keyboard or selecting
 a menu item from the menu with the mouse. While waiting for the user to interact with the application Word does nothing. (Actually I lie: it
<i>does</i> do things like run spell checking and auto save in the background but nothing you as the user can see). Generally, programs written using the Windows Forms library generally have the same behavior – they don’t consume CPU time unless the user is
 doing something (of course, it’s possible to use the Timer control or the capabilities of the System.Threading namespace to do things independent of the user).
</p>
<p>Games are different. As you know, smooth movement in games requires the screen to be updated many times per second. The “flicker fusion threshold” at which static images begin to fuse is generally taken to be 1/16 of a second, although it actually varies
 depending on illumination (brighter lights like computer monitors require higher frame rates) and where on the retina the image falls (peripheral vision requires higher rates than foveal vision). Although movies are shown at 24 frames per second (FPS), 30
 FPS is often considered the lowest-acceptable rate for video games, and most actiongame players tune their graphics for no less than 60 FPS.
</p>
<p>Because the render loop is called dozens of times per second and runs nonstop, game programming almost always uses the render loop as the “stopwatch” of the game, calculating everything inside the loop, not just graphics, but physics, AI, checking for user
 input, and scores. (Again, you <i>could</i> use the Timer class or threads to write a multithreaded game, but doing so would introduce significant complexity without any clear benefits and although multithreading in the .NET Framework’s Common Language Runtime
 &nbsp;is quite efficient, the slight overhead could knock a couple frames per second off your game.)
</p>
<p>So how do we get the computer to run this loop? The form we added earlier has an event called the
<i>Paint</i> event. The <i>Paint</i> event for a Windows Form object is called whenever the form is redrawn. This normally occurs only when you maximize a form or when a form is covered by another form that is moved.
</p>
<p>As all Windows Forms programming, even game programming, is event-based, understanding the principles of events and event handlers is critical. Although the event is triggered automatically, we need to create a special method called an event handler to be
 able to intercept the event and do something in response to it.. </p>
<ul>
<li>In the GameEngine class add the following code after the constructor. </li></ul>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnPaint(PaintEventArgs e)<br>{<br>          <br>}</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Protected</span> <span class="kwrd">Overrides</span> <span class="kwrd">Sub</span> OnPaint(<span class="kwrd">ByVal</span> e <span class="kwrd">As</span> PaintEventArgs)<br>          <br><span class="kwrd">End</span> Sub</pre>
<p><style type="text/css">
   </style></p>
<p>This is our event handler. When is it called? “OnPaint” – when the Paint event occurs. One thing is still missing. Even though Windows and the Windows Forms library automatically raise the event, some actions that we might expect to trigger the Paint event
 don’t. Minimizing a window, for example, does not trigger the Paint event, since Windows does not see the need to repaint the entire form (Windows is just being efficient since we are actually displaying less when we are shrinking the form). So we cannot rely
 on these automatically-created events to manage the loop we need for our game. </p>
<p>Luckily, we can programmatically trigger the Paint event by calling the Invalidate method of a form. This causes the Paint event to be triggered and Windows to enter back into our OnPaint event handler. Then we execute any code we want to run every frame
 and start all over again by calling the Invalidate method. </p>
<p>You might ask, “Why can’t we just add a while(true) loop directly within OnPaint() and never leave it?” The answer is that even though we’re game programmers, we’re expected to play well with others. Creating a loop within OnPaint() would starve the rest
 of the programs running on the system. While our game might gain a few frames per second, the rest of the system would become, at best, ugly, and at worst, unstable. So, instead of directly looping, we essentially “ask” to be called again as soon as possible.
</p>
<ul>
<li>In the OnPaint method add the following line of code: </li></ul>
<p><b>Visual C#</b><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></p>
<pre class="csharpcode"><span class="kwrd">this</span>.Invalidate();</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Me</span>.Invalidate()</pre>
<p><style type="text/css">
   </style></p>
<p>That’s it, we’ve created our render loop. But there is one more problem. It turns out that not
<i>all</i> painting is done in the OnPaint method, Windows Forms triggers another event when the background is erased and by default performs some painting (well, erasing) in response. To force our application to truly only paint inside our method handler,
 we need to add one more line of code to our application. Since we need to ensure that this code is run when the application starts, we place it into the constructor of the form. This means that we are guaranteed that this code is run before we call any methods
 on that class. </p>
<ul>
<li>In the GameEngine class add the following line of code to the constructor immediately following the InitializeComponent method call.
</li></ul>
<p><b>Visual C#</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">this</span>.SetStyle(ControlStyles.AllPaintingInWmPaint |<br>    ControlStyles.Opaque, <span class="kwrd">true</span>);</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Me</span>.SetStyle(ControlStyles.AllPaintingInWmPaint <span class="kwrd">Or</span> <br>    ControlStyles.Opaque, <span class="kwrd">True</span>)</pre>
<p><style type="text/css">
   </style></p>
<p>Setting the ControlStyles to AllPaintingInWmPaint ensures that Windows only uses the OnPaint event handler to redraw the screen. The second parameter simply informs Windows that our window is not going to be transparent.
</p>
<p>Now we have the basic framework for our game. Everything we are going to create from now on out will be actions that occur inside the render loop.
</p>
<h4>Everything about timers</h4>
<p>One issue with this type of loop is that fact that the speed in which the computer can accomplish the tasks in the render loop varies from computer to computer. It even varies on the same computer according to how much memory and CPU time is available for
 the game at any given moment. We need to have some way of accounting for these differences to make sure that we animate consistently. So instead of treating each frame the same, we are going to calculate the time elapsed between frames and apply that value
 to our calculations. </p>
<p>There are a couple of different ways of keeping track of time in Windows: </p>
<ol>
<li><b>System.Windows.Forms.Timer</b>: This is the most common timer used in Windows programming. While it is easy to use, it only has a resolution of 1/18<sup>th</sup> of a second. Since we could have up to a thousand frames per second this resolution is not
 good enough for a game program. </li><li><b>timeGetTime</b>: This Windows DLL provides a resolution of 1 microsecond on some versions of Windows and 5 microseconds on Windows NT. This is too variable, and we really don’t want to check the operating system our game is running on to see if we need
 to adjust the timer values. </li><li><b>System.TickCount</b>: This managed call returns the number of ticks that indicate the number of milliseconds. This is close to what we want, but we can do better.
</li><li><b>QueryPerformanceCounter</b>: This is the preferred timer to use; it has a resolution of less than 1 microsecond. This is the timer most often used in game development.
</li></ol>
<p>The last timer is kind of tricky to write since it requires calls to a low-level DLL (kernel32 if you need to know) in Windows. Luckily for us the need for a high-resolution timer is universal and a timer class is included with the DirectX SDK. You can find
 the timer class in the \Samples\Managed\Common directory underneath the install directory of the SDK. The file we are interested in is called dxmutmisc.cs, but we will use most of the other files in that directory as we add more functionality to our own project.
</p>
<p>Before we add dxmutmisc.cs we are going to create a separate folder. Organizing a solution by folders makes it easy to group related items together and keeps the project more organized.
</p>
<ul>
<li>Selecting <b>Add | New Folder</b>. Name the new folder: <b>DirectXSupport</b>. This is where we are going to add the various support classes as we make use of them throughout this project.
</li></ul>
<p>Now we are going to add the existing file to our project. This copies the file to our directory structure.&nbsp;
</p>
<ul>
<li>Right-click the DirectXSupport folder and select Add | Add Existing Item and browse to C:\Program Files\Microsoft DirectX 9.0 SDK (February 2005)\Samples\Managed\Common and select the dxmutmisc.cs file.
</li></ul>
<p>If you want to, you can browse the contents of this file, it contains various other helper classes that save you from writing a lot of code yourself in addition to the FrameworkTimer class
</p>
<p>Since the timer class is contained in a different namespace we are going to add a
<code>using</code> statement so we can use the FrameworkTimer without having to write “Microsoft.Samples.DirectX.UtilityToolkit.FrameworkTimer” every time.
</p>
<ul>
<li>At the top of the class in the using directives region add the following line of code:
</li></ul>
<p><b>Visual C#</b></p>
<pre class="csharpcode">Microsoft.Samples.DirectX.UtilityToolkit;</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre><code></code></pre>
<pre class="csharpcode">Microsoft.Samples.DirectX.UtilityToolkit</pre>
<p><style type="text/css">
   </style></p>
<p>Next we need to have a way to store the value of the time elapsed. We are going to store this value in the deltaTime variable. Notice that we are declaring this variable as a double. If you declared it as an integer you would lose all of the resolution provided
 by our high-powered timer since everything would be rounded to an integer. </p>
<ul>
<li>At the end of the class above the last two braces add the following line of code.
</li></ul>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">double</span> deltaTime;</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Private</span> deltaTime <span class="kwrd">As</span> Double</pre>
<p><style type="text/css">
   </style></p>
<p>We want to start the timer at the last possible moment in the render loop so we can get the most accurate time possible.
</p>
<ul>
<li>At the end of the OnPaint method right before the this.Invalidate call add the following code.
</li></ul>
<p><b>Visual C#</b><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></p>
<pre class="csharpcode">FrameworkTimer.Start();</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode">Microsoft.Samples.DirectX.UtilityToolkit.FrameworkTimer.Start()</pre>
<p><style type="text/css">
   </style></p>
<p>We need to calculate the elapsed (or delta) time at the start of each loop, because we are going to pass it to most of the subsequent calls we are going to make.
</p>
<ul>
<li>At the very top of the OnPaint method, before any other code, add the following line of code.
</li></ul>
<p><b>Visual C#</b></p>
<pre class="csharpcode">deltaTime = FrameworkTimer.GetElapsedTime();</pre>
<p><style type="text/css">
   </style></p>
<p><b>Visual Basic</b></p>
<pre class="csharpcode">deltaTime = Microsoft.Samples.DirectX.UtilityToolkit.FrameworkTimer.GetElapsedTime()</pre>
<p><style type="text/css">
   </style></p>
<p>That’s it. We now have a way to track time. As an added bonus, in the next article, we will use this timer to compute our frame rate. You will notice that the solution now will no longer build. This is because the classes in the file we added require DirectX
 to be referenced. We are going to cover which parts of DirectX we need in the next article.
</p>
<h4>Summary</h4>
<p>We have accomplished a lot in this first article. First, we covered the tools needed to created managed DirectX games and then we discussed the features that make a great game. Next, we defined our game idea and created our game project. After that, we created
 the render loop we are going to use throughout the game, and finally we added a high resolution timer to our project.&nbsp;
</p>
<p>The next steps all require DirectX, which we will cover in the next article. I hope that this initial article has motivated you to begin that game you always thought about. Game development can be one of the most satisfying experiences in computer programming,
 and as we progress through this series, I am going to teach you all the fundamentals you need to accomplish that goal.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1d90c2033e04443faf539e7600d9942b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-I--Introduction</comments>
      <itunes:summary>



&amp;nbsp;

This is Part 1 of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0. 
WARNING: Managed DirectX is no longer supported.&amp;nbsp; If you want to do 3D graphics with the .NET Framework, please use XNA (http://creators.xna.com) 




Derek Pierson
3Leaf Development

Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions,
DirectX SDK
Hardware: None
&amp;nbsp;
Beginning Game Development Series


Beginning Game Development Part 1 - Introduction

Beginning Game Development Part II - Introduction to DirectX

Beginning Game Development: Part III - DirectX II

Beginning Game Development: Part IV - DirectInput

Beginning Game Development: Part V - Adding Units


Beginning Game Development: Part VI - Lights, Materials and Terrain

Beginning Game Development: Part VII –Terrain and Collision Detection

Beginning Game Development: Part VIII - DirectSound


Beginning Game Development: Part VIII - DirectSound II




Beginning Game Development: Part VIII - DirectSound III







Part I – Introduction  
Welcome to the first article of an introductory series on game programming using the Microsoft .NET Framework and managed DirectX 9.0.
 
This series as aimed at beginning programmers who are interested in developing a game for their own use with the .NET Framework and DirectX. The goal of this series is to have fun creating a game and learn game development and DirectX along the way. Game
 programming and DirectX have their own terms and definitions that can be difficult to understand, but after awhile, you’ll crack the code and be able to explore a new world of possibilities. I will keep things as straightforward as possible and decode terms
 as they appear. Another part of the learning curve comes from the math you’ll need to deal with DirectX. I am going to point out some resources along the way that will help you brush up on, or learn, the math skills you’ll need to ke</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-I--Introduction</link>
      <pubDate>Fri, 03 Nov 2006 03:51:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-I--Introduction</guid>      
      <dc:creator>Derek Pierson</dc:creator>
      <itunes:author>Derek Pierson</itunes:author>
      <slash:comments>42</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Beginning-Game-Development-Part-I--Introduction/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>2D Game Primer (Visual C#)</title>
      <description><![CDATA[<span id="c4fmetadata">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">This article is a part of Upgrade Your Game series of tutorials. It covers some of the fundamentals of simple math needed for the games in this series.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">The Z-man Andy Dunn</div>
<div class="entry_company"><a href="http://www.thezbuffer.com/">The Z Buffer</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a>Not available</a> </li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>&nbsp;</p>
<h4>Introduction</h4>
<p>Welcome to the Upgrade Your Game series of tutorials. There are four tutorials, each covering how to write a simple computer game using Visual Studio Express products. Though the games are simple, each one teaches some game development techniques and builds
 on the last to improve your skills. The skills can be applied to more complex games including 3D games using
<a href="http://msdn.microsoft.com/directx/">Microsoft DirectX</a>. </p>
<p>When you program games, you have to use math whether you want to or not. The simpler the game, the less math there is to learn, and 2D games use simpler math — but you cannot avoid it altogether. Today's top-selling 3D games are full of 3D vector math and
 complex simulations of physics. Fortunately, you do not need to know all of that for the simple games presented in this series.
</p>
<p>This 2D primer covers some of the fundamentals of simple math needed for the games in this series.
</p>
<p><b>Note:</b> This documentation assumes that you have a basic knowledge of programming concepts and the Visual C# environment. You can learn more about these topics in the product documentation by clicking
<b>Help</b> on the menu bar, and then clicking <b>Contents</b>, <b>Index</b>, or <b>
Search</b>. You can also access Help by positioning the mouse cursor on language keywords or user interface elements such as windows or dialog boxes, and pressing F1.
</p>
<h4>2D Game Development Concepts</h4>
<h5><b>The Game Loop</b></h5>
<p>Window Forms and ASP applications are often called &quot;event-driven&quot; applications — they sit doing nothing for most of the time waiting for an external stimulus, such as a button press from an end user or a Web service request from another application. This
 works really well for that kind of application. </p>
<p>Games, on the other hand, are generally not sitting doing nothing all the time. Even if the end user is not pressing a key or a button on the gamepad, the game must animate characters, perform AI functions, and play sounds and many other things depending
 on the game. You've probably done some of these background type tasks in Windows Forms applications using timer controls or background threads. But in general these don't scale to the computer game scenario, where there are multiple animations and multiple
 background tasks all happening at very different intervals. </p>
<p>The solution that most games use (and by &quot;most games&quot; I mean everything right up to the top-selling Xbox 360 titles) is usually called the &quot;game loop.&quot; In pseudo code it looks something like this:
</p>
<pre class="csharpcode"><span class="kwrd"></span>    While (game is running)<br>        Check for input<br>        Update all objects in the game <br>        Draw all objects in the game<br></pre>
<div class="postBody" id="da00c60d-7813-4288-b54a-0527b29a609d"><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:Consolas,"Courier New",Courier,Monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style></div>
<p>This might explain one reason why games almost always use 100% of your CPU even if they don't appear to be doing much. The faster your computer is, the faster this loop will run and the smoother the animation and the synchronization will be.
</p>
<p>There is one slight problem with running a tight loop like that, at least in Windows. If you don't allow Windows to check for and process Windows messages and events, your application will be marked as &quot;Not responding&quot; by the operating system. You might
 have seen this in your applications if you have a loop that runs for a long time. You might also have solved it by putting a call to DoEvents into the loop, which allows Windows to process the events. This can work reasonably well if you know the loop will
 end eventually, but in this case the loop is the entire game and you need a better way.
</p>
<p>The method I have chosen to use for these games is NOT the most efficient (for a full discussion on this under Managed DirectX see the
<a href="http://www.thezbuffer.com/articles/185.aspx">MDX Game Loop FAQ</a>), but it is the simplest, and none of the games covered here needs the more complex method.
</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> TinyTennis_Paint(<span class="kwrd">object</span> sender, PaintEventArgs e)<br>{<br>    <span class="rem">//Work out how long since we were last here</span><br>    <span class="kwrd">in</span> seconds<br>    <span class="kwrd">double</span> gameTime = _timer.ElapsedMilliseconds / 1000.0;<br>    <span class="kwrd">double</span> elapsedTime = gameTime - _lastTime;<br>    _lastTime = gameTime;<br>    _frameCounter&#43;&#43;;<br> <br>    <span class="rem">//Perform any animation</span><br><br>    <span class="rem">//Draw the game objects</span><br> <br>   <span class="rem">//Force the next Paint()</span><br>    <span class="kwrd">this</span>.Invalidate();<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h5><b>Sprites</b></h5>
<p><a href="http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29">Sprites</a> are two-dimensional images that appear in a video game. Sometimes they are static images, but in general they are the building blocks for animation. They either move around
 the screen or change the image at regular intervals, giving a &quot;flip book&quot; kind of animation; or they do both, giving you characters like Mario and Donkey Kong that can move around the screen running and jumping.
</p>
<h5><b>Positioning a Sprite</b></h5>
<p>Just like Windows Forms controls, sprites are placed at an x,y position on the form. 0,0 is the top left and ClientSize.Width, ClientSize.Height is the bottom right. Just like Windows Forms controls, sprites have a height and width too.
</p>
<p>However, unlike Windows Forms controls, sprites are primarily designed to move and animate, often hundreds of times per second, to get the smoothest animation possible. So while a sprite can only be drawn at an integer x,y position, its ACTUAL position at
 a subsecond point in time could be 1.45, 12.67. It's important to remember this position so that the animation doesn't get choppy. A sprite position is stored using a floating-point Point structure PointF rather than the integer-based Point structure like
 Windows Forms controls. This means you can store the subpixel accuracy and then just convert to integer screen positions when you draw them.
</p>
<h5><b>Vectors</b></h5>
<p>The more game programming you do, the more you will come across the term &quot;vector.&quot; Though I've avoided the term in this series for the sake of simplicity, it's worth noting that the concepts are used when the positions of the sprites are updated for animation.
</p>
<p>Simply put, a vector is just an offset. So a vector of (4,2) means that from some start point you move 4 units in the x-axis and 2 in the y-axis.
</p>
<p>You will see positions referred to as vectors. In this case, a position of (4,2) means an offset of (4,2) from the origin.
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916381/2dprimer1.png" alt="" border="0">
</p>
<p>Vectors can be added together, so (4,2) &#43; (2,4) gives you a total offset of (6,6).
</p>
<p>Vectors can have negative components, so (-2,1) means move 2 units to the left on the x-axis and 1 unit down on the y-axis.
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916381/2dprimer2.png" alt="" border="0">
</p>
<p>All of these concepts are used when moving a sprite around the screen. </p>
<h5><b>Moving a Sprite</b></h5>
<p>Sprites move with a certain velocity. Velocity is different from speed because velocity also contains information about the direction. For example, you could tell me you are driving at 60 mph, and I would guess that in one hour you would be 60 miles from
 the start point. But if you were driving round in a circle, that would not be the case. If I told you my velocity was 60 mph due east, then I would know for sure where you would end up.
</p>
<p>Since your position is an x, y value you can store your velocity as another two-component vector (s, t): s is how fast you want to move on the x-axis, and t is how fast you want to move on the y-axis. If you add them together: (x,y) &#43; (s,t) = (x&#43;s, y&#43;t),
 you get the new position of the sprite. </p>
<p><b>Example: </b>Sprite is at (4,10) and has a speed of (1,0). (1,0) means the sprite will move right in the x direction only. (4,10) &#43; (1,0) = (5,10). If you repeat this addition every second, then the sprite will move 1 pixel per second across the screen.
 You can see that any direction and speed can be represented just by changing the s, t values in that vector.
</p>
<h5><b>Time-Based Animation</b></h5>
<p>Imagine a sprite that starts at x=0 and is moving to the right with a velocity of &#43;10. If you walk through the game loop above, the sprite would have &#43;10 added to its position each time the sprite was updated and would move from x=0 to x={some bigger number}
 where {some bigger number} is 10 times the number of times the loop has been run. But the question is, exactly how fast would it move? Well, it depends on how fast the loop runs, which depends on how fast your computer is running. This would mean that on your
 top-of-the-line gaming rig the sprite could cross the screen in half a second, but on your parents' four-year-old &quot;we only use it for e-mail&quot; computer it could take two seconds. Obviously this isn't something that is desirable in a computer game.
</p>
<p>To fix this you need to think about what velocity really is. What does that &#43;10 mean? Velocity is a measure of distance over a period of time, so you cannot think of the &#43;1 as just a distance; it's really &#43;1 pixel in some time that you need to define. So
 each time round the loop, you just need to know how long it's been since the last update and scale the movement by that time.
</p>
<p>A sprite that has a velocity of &#43;10 actually means you move &#43;10 pixels per second. So if it's been half a second since the last frame, multiply that by the velocity and move 5 pixels. In reality the time between frames is fractions of a second. So on your
 fast gaming rig, where the loop runs very fast, the sprite will move with subpixel accuracy for some very smooth animation. On your parents' computer, where the loop only runs 5 times per second, the sprite will move 2 pixels each frame, but after 10 seconds
 the sprite will be in exactly the same place as it is on your computer. </p>
<p>The code will look something like this (notice that for accuracy elapsedTime is a double and therefore needs to be cast down to a float to match the PointF structure):
</p>
<pre><code></code></pre>
<pre class="csharpcode">    <span class="rem">//Move the sprite based on the velocity</span><br>    Location.X &#43;= Velocity.X * (<span class="kwrd">float</span>)elapsedTime;<br>    Location.Y &#43;= Velocity.Y * (<span class="kwrd">float</span>)elapsedTime;<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The loop timings I mentioned here are very exaggerated — on most computers the loop will be running hundreds or thousands of times per second, meaning that your animations will be very smooth and accurate.
</p>
<h5><b>Sprite bounds</b></h5>
<p>There are two ways to represent the rectangle containing the sprite: </p>
<ol>
<li>X, Y, Height, Width </li><li>X, Y of top left corner and X, Y of bottom right corner </li></ol>
<p>Whilst both of these are valid, you must usually find the first one in use. It's easier to update just one corner as the sprite moves around and calculate the other corner when it's needed. For tasks like collisions- and bounds-checking you need to calculate
 the bottom-right corner, so you will see X&#43;Width and Y&#43;Height as a very commonly used formula in games.
</p>
<h5><b>Simple Collision Detection</b></h5>
<p>Collisions are a vital part of almost any game — they restrict where an object can move, whether an object has taken damage, and so forth.
</p>
<p>Simple collisions can be described in terms of the positions and size of the sprites and the regions they need to collide with. Since everything is rectangular in this case, there is no need for any more complex collisions that need to be determined at the
 pixel level. All the collisions can be checked for by looking to see if the rectangles overlap or if the coordinates are outside of a certain range. Checking for rectangle overlap is
<a href="http://www.tekpool.com/?p=23">quite simple</a>. </p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> collide()<br>{<br><span class="kwrd">return</span> ! ( sprite1.Location.X &gt; sprite2.Location.X &#43; sprite2.Size.Width<br>    || sprite1.Location.X &#43; sprite1.Size.Width  &lt; sprite2.Location.X<br>    || sprite1.Location.Y &gt; sprite2.Location.Y &#43; sprite2.Size.Height<br>    || sprite1.Location.Y &#43; sprite1.Size.Height &lt; sprite2.Location.Y);<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This code uses an efficient algorithm for determining if the two rectangles overlap. It checks the bounds of both rectangles to determine whether they DON'T overlap and then negates the result. For example, the first line checks whether the left-hand edge
 of sprite 1 is to the right of the right-hand edge of sprite 2. If it is, then obviously they cannot overlap. The next three lines check the other three edges.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:591d31c12b174336bb739e7600da28e6">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-C</comments>
      <itunes:summary>



&amp;nbsp;
This article is a part of Upgrade Your Game series of tutorials. It covers some of the fundamentals of simple math needed for the games in this series.



The Z-man Andy Dunn
The Z Buffer

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
Download: 

Not available 






&amp;nbsp; 
Introduction
Welcome to the Upgrade Your Game series of tutorials. There are four tutorials, each covering how to write a simple computer game using Visual Studio Express products. Though the games are simple, each one teaches some game development techniques and builds
 on the last to improve your skills. The skills can be applied to more complex games including 3D games using
Microsoft DirectX.  
When you program games, you have to use math whether you want to or not. The simpler the game, the less math there is to learn, and 2D games use simpler math — but you cannot avoid it altogether. Today&#39;s top-selling 3D games are full of 3D vector math and
 complex simulations of physics. Fortunately, you do not need to know all of that for the simple games presented in this series.
 
This 2D primer covers some of the fundamentals of simple math needed for the games in this series.
 
Note: This documentation assumes that you have a basic knowledge of programming concepts and the Visual C# environment. You can learn more about these topics in the product documentation by clicking
Help on the menu bar, and then clicking Contents, Index, or 
Search. You can also access Help by positioning the mouse cursor on language keywords or user interface elements such as windows or dialog boxes, and pressing F1.
 
2D Game Development Concepts
The Game Loop
Window Forms and ASP applications are often called &amp;quot;event-driven&amp;quot; applications — they sit doing nothing for most of the time waiting for an external stimulus, such as a button press from an end user or a Web service request from another application. This
 works really well for that ki</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-C</link>
      <pubDate>Tue, 31 Oct 2006 23:04:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-C</guid>      
      <dc:creator>Andy Dunn</dc:creator>
      <itunes:author>Andy Dunn</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-C/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>
  <item>
      <title>2D Game Primer (Visual Basic)</title>
      <description><![CDATA[<span id="c4fmetadata">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">This article is a part of Upgrade Your Game series of tutorials. It covers some of the fundamentals of simple math needed for the games in this series.</span><br>
</td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">The Z-man Andy Dunn</div>
<div class="entry_company"><a href="http://www.thezbuffer.com/">The Z Buffer</a></div>
<div class="entry_company"><a href="http://www.thezbuffer.com/"></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a>Not available</a> </li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<h4>Introduction</h4>
<p>Welcome to the Upgrade Your Game series of tutorials. There are four tutorials, each covering how to write a simple computer game using Visual Studio Express products. Though the games are simple, each one teaches some game development techniques and builds
 on the last to improve your skills. The skills can be applied to more complex games including 3D games using
<a href="http://msdn.microsoft.com/directx/">Microsoft DirectX</a>. </p>
<p>When you program games, you have to use math whether you want to or not. The simpler the game, the less math there is to learn, and 2D games use simpler math — but you cannot avoid it altogether. Today's top-selling 3D games are full of 3D vector math and
 complex simulations of physics. Fortunately, you do not need to know all of that for the simple games presented in this series.
</p>
<p>This 2D primer covers some of the fundamentals of simple math needed for the games in this series.
</p>
<p><b>Note:</b> This documentation assumes that you have a basic knowledge of programming concepts and the Visual Basic environment. You can learn more about these topics in the product documentation by clicking
<b>Help</b> on the menu bar, and then clicking <b>Contents</b>, <b>Index</b>, or <b>
Search</b>. You can also access Help by positioning the mouse cursor on language keywords or user interface elements such as windows or dialog boxes, and pressing F1.
</p>
<h4>2D Game Development Concepts</h4>
<h5>The Game Loop</h5>
<p>Window Forms and ASP applications are often called &quot;event-driven&quot; applications — they sit doing nothing for most of the time waiting for an external stimulus, such as a button press from an end user or a Web service request from another application. This
 works really well for that kind of application. </p>
<p>Games, on the other hand, are generally not sitting doing nothing all the time. Even if the end user is not pressing a key or a button on the gamepad, the game must animate characters, perform AI functions, and play sounds and many other things depending
 on the game. You've probably done some of these background type tasks in Windows Forms applications using timer controls or background threads. But in general these don't scale to the computer game scenario, where there are multiple animations and multiple
 background tasks all happening at very different intervals. </p>
<p>The solution that most games use (and by &quot;most games&quot; I mean everything right up to the top-selling Xbox 360 titles) is usually called the &quot;game loop.&quot; In pseudo code it looks something like this:
</p>
<pre class="csharpcode">    While (game is running)<br>        Check for input<br>        Update all objects in the game <br>        Draw all objects in the game</pre>
<p>This might explain one reason why games almost always use 100% of your CPU even if they don't appear to be doing much. The faster your computer is, the faster this loop will run and the smoother the animation and the synchronization will be.
</p>
<p>There is one slight problem with running a tight loop like that, at least in Windows. If you don't allow Windows to check for and process Windows messages and events, your application will be marked as &quot;Not responding&quot; by the operating system. You might
 have seen this in your applications if you have a loop that runs for a long time. You might also have solved it by putting a call to DoEvents into the loop, which allows Windows to process the events. This can work reasonably well if you know the loop will
 end eventually, but in this case the loop is the entire game and you need a better way.
</p>
<p>The method I have chosen to use for these games is NOT the most efficient (for a full discussion on this under Managed DirectX see the
<a href="http://www.thezbuffer.com/articles/185.aspx">MDX Game Loop FAQ</a>), but it is the simplest, and none of the games covered here needs the more complex method.
</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> TinyTennis_Paint(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> PaintEventArgs) <span class="kwrd">Handles</span> <span class="kwrd">MyBase</span>.Paint<br>    <span class="rem">'Perform any animation here</span><br> <br>    <span class="rem">'Draw the game objects here</span><br> <br>    <span class="rem">'Force the next Paint()</span><br>    <span class="kwrd">Me</span>.Invalidate()<br><span class="kwrd">End</span> <span class="kwrd">Sub</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Sprites</b></p>
<p><a href="http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29">Sprites</a> are two-dimensional images that appear in a video game. Sometimes they are static images, but in general they are the building blocks for animation. They either move around
 the screen or change the image at regular intervals, giving a &quot;flip book&quot; kind of animation; or they do both, giving you characters like Mario and Donkey Kong that can move around the screen running and jumping.
</p>
<h5>Positioning a Sprite</h5>
<p>Just like Windows Forms controls, sprites are placed at an x,y position on the form. 0,0 is the top left and ClientSize.Width, ClientSize.Height is the bottom right. Just like Windows Forms controls, sprites have a height and width too.
</p>
<p>However, unlike Windows Forms controls, sprites are primarily designed to move and animate, often hundreds of times per second, to get the smoothest animation possible. So while a sprite can only be drawn at an integer x,y position, its ACTUAL position at
 a subsecond point in time could be 1.45, 12.67. It's important to remember this position so that the animation doesn't get choppy. A sprite position is stored using a floating-point Point structure PointF rather than the integer-based Point structure like
 Windows Forms controls. This means you can store the subpixel accuracy and then just convert to integer screen positions when you draw them.
</p>
<h5><b>Vectors</b></h5>
<p>The more game programming you do, the more you will come across the term &quot;vector.&quot; Though I've avoided the term in this series for the sake of simplicity, it's worth noting that the concepts are used when the positions of the sprites are updated for animation.
</p>
<p>Simply put, a vector is just an offset. So a vector of (4,2) means that from some start point you move 4 units in the x-axis and 2 in the y-axis.
</p>
<p>You will see positions referred to as vectors. In this case, a position of (4,2) means an offset of (4,2) from the origin.
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916368/2dprimer1.png" alt="" border="0">
</p>
<p>Vectors can be added together, so (4,2) &#43; (2,4) gives you a total offset of (6,6).
</p>
<p>Vectors can have negative components, so (-2,1) means move 2 units to the left on the x-axis and 1 unit down on the y-axis.
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/916368/2dprimer2.png" alt="" border="0">
</p>
<p>All of these concepts are used when moving a sprite around the screen. </p>
<h5><b>Moving a Sprite</b></h5>
<p>Sprites move with a certain velocity. Velocity is different from speed because velocity also contains information about the direction. For example, you could tell me you are driving at 60 mph, and I would guess that in one hour you would be 60 miles from
 the start point. But if you were driving round in a circle, that would not be the case. If I told you my velocity was 60 mph due east, then I would know for sure where you would end up.
</p>
<p>Since your position is an x, y value you can store your velocity as another two-component vector (s, t): s is how fast you want to move on the x-axis, and t is how fast you want to move on the y-axis. If you add them together: (x,y) &#43; (s,t) = (x&#43;s, y&#43;t),
 you get the new position of the sprite. </p>
<p><b>Example: </b>Sprite is at (4,10) and has a speed of (1,0). (1,0) means the sprite will move right in the x direction only. (4,10) &#43; (1,0) = (5,10). If you repeat this addition every second, then the sprite will move 1 pixel per second across the screen.
 You can see that any direction and speed can be represented just by changing the s, t values in that vector.
</p>
<h5><b>Time-Based Animation</b></h5>
<p>Imagine a sprite that starts at x=0 and is moving to the right with a velocity of &#43;10. If you walk through the game loop above, the sprite would have &#43;10 added to its position each time the sprite was updated and would move from x=0 to x={some bigger number}
 where {some bigger number} is 10 times the number of times the loop has been run. But the question is, exactly how fast would it move? Well, it depends on how fast the loop runs, which depends on how fast your computer is running. This would mean that on your
 top-of-the-line gaming rig the sprite could cross the screen in half a second, but on your parents' four-year-old &quot;we only use it for e-mail&quot; computer it could take two seconds. Obviously this isn't something that is desirable in a computer game.
</p>
<p>To fix this you need to think about what velocity really is. What does that &#43;10 mean? Velocity is a measure of distance over a period of time, so you cannot think of the &#43;1 as just a distance; it's really &#43;1 pixel in some time that you need to define. So
 each time round the loop, you just need to know how long it's been since the last update and scale the movement by that time.
</p>
<p>A sprite that has a velocity of &#43;10 actually means you move &#43;10 pixels per second. So if it's been half a second since the last frame, multiply that by the velocity and move 5 pixels. In reality the time between frames is fractions of a second. So on your
 fast gaming rig, where the loop runs very fast, the sprite will move with subpixel accuracy for some very smooth animation. On your parents' computer, where the loop only runs 5 times per second, the sprite will move 2 pixels each frame, but after 10 seconds
 the sprite will be in exactly the same place as it is on your computer. </p>
<p>The code will look something like this (notice that for accuracy elapsedTime is a double and therefore needs to be cast down to a float to match the PointF structure):
</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="rem">'Move the sprite based on the velocity</span><br>Location.X &#43;= Velocity.X * <span class="kwrd">CSng</span>(elapsedTime)<br>Location.Y &#43;= Velocity.Y * <span class="kwrd">CSng</span>(elapsedTime)<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The loop timings I mentioned here are very exaggerated — on most computers the loop will be running hundreds or thousands of times per second, meaning that your animations will be very smooth and accurate.
</p>
<h5>Sprite bounds</h5>
<p>There are two ways to represent the rectangle containing the sprite: </p>
<ol>
<li>X, Y, Height, Width </li><li>X, Y of top left corner and X, Y of bottom right corner </li></ol>
<p>Whilst both of these are valid, you must usually find the first one in use. It's easier to update just one corner as the sprite moves around and calculate the other corner when it's needed. For tasks like collisions- and bounds-checking you need to calculate
 the bottom-right corner, so you will see X&#43;Width and Y&#43;Height as a very commonly used formula in games.
</p>
<h5>Simple Collision Detection</h5>
<p>Collisions are a vital part of almost any game — they restrict where an object can move, whether an object has taken damage, and so forth.
</p>
<p>Simple collisions can be described in terms of the positions and size of the sprites and the regions they need to collide with. Since everything is rectangular in this case, there is no need for any more complex collisions that need to be determined at the
 pixel level. All the collisions can be checked for by looking to see if the rectangles overlap or if the coordinates are outside of a certain range. Checking for rectangle overlap is
<a href="http://www.tekpool.com/?p=23">quite simple</a>. </p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Function</span> collide() <span class="kwrd">As</span> <span class="kwrd">Boolean</span><br>    <span class="kwrd">Return</span> <span class="kwrd">Not</span> (Sprite1.Location.X &gt; Sprite2.Location.X &#43; Sprite2.Size.Width      <span class="kwrd">OrElse</span> _<br>    Sprite1.Location.X &#43; Sprite1.Size.Width  &lt; Sprite2.Location.X <span class="kwrd">OrElse</span> _<br>    Sprite1.Location.Y &gt; Sprite2.Location.Y &#43; Sprite2.Size.Height <span class="kwrd">OrElse</span> _<br>    Sprite1.Location.Y &#43; Sprite1.Size.Height &lt; Sprite2.Location.Y)<br><span class="kwrd">End</span> Function</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This code uses an efficient algorithm for determining if the two rectangles overlap. It checks the bounds of both rectangles to determine whether they DON'T overlap and then negates the result. For example, the first line checks whether the left-hand edge
 of sprite 1 is to the right of the right-hand edge of sprite 2. If it is, then obviously they cannot overlap. The next three lines check the other three edges.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/arcade/RSS&WT.dl=0&WT.entryid=Entry:RSSView:dbe04b168e9848f49ae19e7600da2b15">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-Basic</comments>
      <itunes:summary>



&amp;nbsp;
This article is a part of Upgrade Your Game series of tutorials. It covers some of the fundamentals of simple math needed for the games in this series.




The Z-man Andy Dunn
The Z Buffer


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
Download: 

Not available 






Introduction
Welcome to the Upgrade Your Game series of tutorials. There are four tutorials, each covering how to write a simple computer game using Visual Studio Express products. Though the games are simple, each one teaches some game development techniques and builds
 on the last to improve your skills. The skills can be applied to more complex games including 3D games using
Microsoft DirectX.  
When you program games, you have to use math whether you want to or not. The simpler the game, the less math there is to learn, and 2D games use simpler math — but you cannot avoid it altogether. Today&#39;s top-selling 3D games are full of 3D vector math and
 complex simulations of physics. Fortunately, you do not need to know all of that for the simple games presented in this series.
 
This 2D primer covers some of the fundamentals of simple math needed for the games in this series.
 
Note: This documentation assumes that you have a basic knowledge of programming concepts and the Visual Basic environment. You can learn more about these topics in the product documentation by clicking
Help on the menu bar, and then clicking Contents, Index, or 
Search. You can also access Help by positioning the mouse cursor on language keywords or user interface elements such as windows or dialog boxes, and pressing F1.
 
2D Game Development Concepts
The Game Loop
Window Forms and ASP applications are often called &amp;quot;event-driven&amp;quot; applications — they sit doing nothing for most of the time waiting for an external stimulus, such as a button press from an end user or a Web service request from another application. This
 works really well for that kind </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-Basic</link>
      <pubDate>Tue, 31 Oct 2006 22:58:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-Basic</guid>      
      <dc:creator>Andy Dunn</dc:creator>
      <itunes:author>Andy Dunn</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/2D-Game-Primer-Visual-Basic/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>arcade</category>
    </item>    
</channel>
</rss>