<?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</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Gary-Farr/Posts/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</title>
      <link>http://channel9.msdn.com/Niners/c4f.Gary-Farr/Posts</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/Niners/c4f.Gary-Farr/Posts</link>
    <language>en</language>
    <pubDate>Mon, 20 May 2013 07:33:36 GMT</pubDate>
    <lastBuildDate>Mon, 20 May 2013 07:33:36 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>RetroCommand</title>
      <description><![CDATA[
<p>In this article, I will discuss how I have built RetroCommand, a Silverlight 2.0 Beta 1 version of a classic arcade game (<a href="http://employees.claritycon.com/gfarr/Retrocommand/Retrocommand.html">play here</a>).&nbsp; I will explain how I used Expression
 Blend along with some of the new and interesting Silverlight 2.0 and WCF features to create a fun and entertaining game that will have us all thinking it was 1980 again!
</p>
<p>I have recently updated the game for Silverlight 2.0 Beta 2.&nbsp; If you would like to access that version of the game you can (<a href="http://employees.claritycon.com/gfarr/RetroCommandSLBeta2/RetroCommand.html" target="_blank">here</a>).&nbsp;
</p>
<p>Gary Farr <br>
<a href="http://www.claritycon.com/coding4fun">Coding4Fun at Clarity</a><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</strong></p>
<strong>Difficulty: </strong>Intermediate <br>
<strong>Time Required:</strong> Greater than 10 hours <br>
<strong>Cost:</strong> Free <br>
<strong>Software:</strong> <a href="http://msdn2.microsoft.com/en-us/vstudio/">Visual Studio 2008</a>,
<a href="http://silverlight.net/GetStarted/">Silverlight 2.0 Beta 1</a>, <a href="http://www.microsoft.com/expression/try-it/default.aspx">
Expressions Blend 2.5 March Preview</a><strong>&nbsp; </strong><br>
<strong>Hardware:</strong> <br>
<strong>Download: <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/RetroCommand.zip">
Download</a></strong> <br>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/image08.png"><img height="285" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/image0_thumb4.png" width="434" border="0"></a>
</p>
<h3>Introduction</h3>
<p>Ah video games!&nbsp; Growing up I've played an array of gaming consoles.&nbsp; I started with the Atari 2600 and followed with Sega, Sega Genesis, Playstation, Dreamcast, Playstation 2, Gamecube, XBOX, and now the Wii.&nbsp; This of course includes countless hours of
 computer and online gaming.&nbsp; Well, I have recently been developing WPF applications and wanted to do something fun with Silverlight since this technology opens so many new doors for web development on the Microsoft platform.&nbsp; Being an avid game player, web
 based games struck a chord with me and I quickly decided my first Silverlight app would be a game.&nbsp; I started researching.&nbsp;
</p>
<p>There is a lot of information out there about game programming in Silverlight.&nbsp;
<a href="http://silverlight.net/blogs/msnow/default.aspx">Mike Snow</a> has some great introductory blog posts.&nbsp;
<a href="http://silverlightrocks.com/Community/blogs/silverlight_games_101/">Silverlight Games 101</a> is also a good source for game development.&nbsp; Of course
<a href="http://silverlight.net/">Silverlight.Net</a> has been posting some great gaming examples since the release of Silverlight 1.0.&nbsp; I also have to give some props to my co-worker Justin Petersen, whose
<a href="http://blogs.msdn.com/coding4fun/archive/2007/09/19/5002772.aspx">Silverlight 8-Ball</a> game helped me actually get started.&nbsp;
</p>
<p>Once the research began, the next step was deciding what video game I should write.&nbsp; I decided to go old school, for several reasons.&nbsp; First, I was somewhat afraid of the design required with newer games.&nbsp; I look back now and would love to give the game
 a Silverlight face lift (RetroCommand 2.0!) but at the time I was still fairly new to this development and didn't want to worry about design features.&nbsp; Second, this is my mother's favorite game, and as I kid I remembered how she would always play it.&nbsp; It just
 seemed like a fun choice.&nbsp; The next step is development!&nbsp; I will now go through the steps I took to create the gaming code as well as some of the technologies I used.
</p>
<h3>Application Startup</h3>
<p>I have two projects my game code, the first being the Web Application hosting my WCF service called RetroCommand_Web, the second my Silverlight client side code called RetroCommand.&nbsp;
</p>
<h3>RetroCommand_Web</h3>
<p>I created a WCF service to retain overall high scores in a central location.&nbsp; This service saves the top 10 high scores to a local file on the host server, as well as pushes these high scores to each user playing the game.&nbsp; One of the cool things this enables
 me to do is to keep a total count of how many people have played my game.&nbsp; The setup of my WCF service is quite simple.&nbsp; I followed a great video tutorial by the
<a href="http://blogs.msdn.com/swiss_dpe_team/archive/2008/03/17/silverlight-2-beta1-wcf-linq-to-sql-a-powerfull-combination.aspx">
Swiss MSDN Team</a> that gives step by step directions on how to set up a WCF service with Silverlight.&nbsp;
</p>
<p>In my WCF service I have two methods: ReturnHighScores and SaveHighScores.&nbsp; ReturnHighScores retunrs the current high scores and SaveHighScores persists the high scores.&nbsp;
</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>public</span> HighScore ReturnHighScores()</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>&nbsp; </pre>
<pre><span>   4:</span>     <span>// Deserialization</span></pre>
<pre><span>   5:</span>     HighScore highScore = <span>null</span>;</pre>
<pre><span>   6:</span>     <span>try</span></pre>
<pre><span>   7:</span>     {</pre>
<pre><span>   8:</span>         XmlSerializer s = <span>new</span> XmlSerializer(<span>typeof</span>(HighScore));</pre>
<pre><span>   9:</span>&nbsp; </pre>
<pre><span>  10:</span>         TextReader r = <span>new</span> StreamReader(HttpRuntime.AppDomainAppPath &#43; <span>&quot;\\HighScores.XML&quot;</span>);</pre>
<pre><span>  11:</span>         highScore = (HighScore)s.Deserialize(r);</pre>
<pre><span>  12:</span>         r.Close();</pre>
<pre><span>  13:</span>     }</pre>
<pre><span>  14:</span>     <span>catch</span> (Exception ex)</pre>
<pre><span>  15:</span>     {</pre>
<pre><span>  16:</span>         Console.WriteLine(<span>&quot;Error opening file!&quot;</span>);</pre>
<pre><span>  17:</span>     }</pre>
<pre><span>  18:</span>&nbsp; </pre>
<pre><span>  19:</span>     <span>return</span> highScore; </pre>
<pre><span>  20:</span> }</pre>
<pre><span>  21:</span>&nbsp; </pre>
<pre><span>  22:</span> <span>public</span> <span>void</span> SaveHighScores(HighScore highScore)</pre>
<pre><span>  23:</span> {</pre>
<pre><span>  24:</span>     <span>try</span></pre>
<pre><span>  25:</span>     {</pre>
<pre><span>  26:</span>         XmlSerializer s = <span>new</span> XmlSerializer(<span>typeof</span>(HighScore));</pre>
<pre><span>  27:</span>         TextWriter w = <span>new</span> StreamWriter(HttpRuntime.AppDomainAppPath &#43; <span>&quot;\\HighScores.XML&quot;</span>);</pre>
<pre><span>  28:</span>         s.Serialize(w, highScore);</pre>
<pre><span>  29:</span>         w.Close();</pre>
<pre><span>  30:</span>     }</pre>
<pre><span>  31:</span>     <span>catch</span> (Exception ex)</pre>
<pre><span>  32:</span>     {</pre>
<pre><span>  33:</span>         <span>throw</span>;</pre>
<pre><span>  34:</span>     }</pre>
<pre><span>  35:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Function</span> ReturnHighScores() <span>As</span> HighScore <span>Implements</span> IService1.ReturnHighScores</pre>
<pre><span>   2:</span>     <span>Dim</span> _highScore <span>As</span> HighScore = <span>Nothing</span></pre>
<pre><span>   3:</span>&nbsp; </pre>
<pre><span>   4:</span>     <span>Try</span></pre>
<pre><span>   5:</span>         <span>Dim</span> s <span>As</span> XmlSerializer = <span>New</span> XmlSerializer(<span>GetType</span>(HighScore))</pre>
<pre><span>   6:</span>&nbsp; </pre>
<pre><span>   7:</span>         <span>Dim</span> r <span>As</span> TextReader = <span>New</span> StreamReader(HttpRuntime.AppDomainAppPath &amp; <span>&quot;\\HighScores.XML&quot;</span>)</pre>
<pre><span>   8:</span>         _highScore = s.Deserialize(r)</pre>
<pre><span>   9:</span>&nbsp; </pre>
<pre><span>  10:</span>         r.Close()</pre>
<pre><span>  11:</span>&nbsp; </pre>
<pre><span>  12:</span>     <span>Catch</span> ex <span>As</span> Exception</pre>
<pre><span>  13:</span>&nbsp; </pre>
<pre><span>  14:</span>     <span>End</span> <span>Try</span></pre>
<pre><span>  15:</span>&nbsp; </pre>
<pre><span>  16:</span>     <span>Return</span> _highScore</pre>
<pre><span>  17:</span>&nbsp; </pre>
<pre><span>  18:</span> <span>End</span> <span>Function</span></pre>
<pre><span>  19:</span>&nbsp; </pre>
<pre><span>  20:</span> <span>Sub</span> SaveHighScores(<span>ByRef</span> _highScore <span>As</span> HighScore) <span>Implements</span> IService1.SaveHighScores</pre>
<pre><span>  21:</span>     <span>Try</span></pre>
<pre><span>  22:</span>         <span>Dim</span> s <span>As</span> XmlSerializer = <span>New</span> XmlSerializer(<span>GetType</span>(HighScore))</pre>
<pre><span>  23:</span>&nbsp; </pre>
<pre><span>  24:</span>         <span>Dim</span> w <span>As</span> System.IO.TextWriter = <span>New</span> StreamWriter(HttpRuntime.AppDomainAppPath &amp; <span>&quot;\\HighScores.XML&quot;</span>)</pre>
<pre><span>  25:</span>         s.Serialize(w, _highScore)</pre>
<pre><span>  26:</span>         w.Close()</pre>
<pre><span>  27:</span>     <span>Catch</span> ex <span>As</span> Exception</pre>
<pre><span>  28:</span>&nbsp; </pre>
<pre><span>  29:</span>     <span>End</span> <span>Try</span></pre>
<pre><span>  30:</span> <span>End</span> Sub</pre>
</div>
</div>
<h3>RetroCommand</h3>
<p>The following section describes the code used to create the Silverlight portion of my application.&nbsp; It will detail initial Expression Blend setup, WCF communication, the gaming loop, missile line creation, and collision testing.&nbsp;
</p>
<h3>Expression Blend</h3>
<p>I used Expression Blend to create initial objects on my game screen.&nbsp; Such objects include missiles, images, cities, clouds, missile lines, and hit test regions.&nbsp; Below are brief descriptions of the user controls I created using Expression Blend.</p>
<p>The Page.xaml is my main user control which contains the definitions of all UI Elements that are part of the game play.&nbsp; For example, all missiles are an instance of a missile user control.&nbsp; Also, all cities are an instance of a city user control.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/Page.XAML5.png"><img height="299" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/Page.XAML_thumb3.png" width="513" border="0"></a></p>
<p>The missileLine.xaml is the Silverlight user control I use for all attack line and defense line instances.&nbsp; During game play, missiles attack your cities and firing bases.&nbsp; You also have the ability to shoot the missiles by firing defense missiles from your
 bases.&nbsp; </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/missileLine3.png"><img height="305" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/missileLine_thumb1.png" width="514" border="0"></a>
</p>
<p>The cloud.xaml is the Silverlight user control that pops up a cloud image and animation when an object is hit.&nbsp;
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/cloud5.png"><img height="301" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8586040/cloud_thumb3.png" width="511" border="0"></a></p>
<p>The remaining user controls are GameOver.xaml, LevelBreak.xaml, Startup.xaml, and CrossCursor.xaml.&nbsp; The first three controls are for non game play messaging and the Cross Cursor is the mouse display.</p>
<p>All user controls have fade in and fade out animations.&nbsp; These animations help make the game play smooth.&nbsp; Examples of this fade in and fade out code are below</p>
<div>
<div>
<pre><span>   1:</span> &lt;Storyboard x:Name=<span>&quot;FadeIn&quot;</span> Completed=<span>&quot;FadeIn_Completed&quot;</span>&gt;</pre>
<pre><span>   2:</span>     &lt;DoubleAnimationUsingKeyFrames Storyboard.TargetName=<span>&quot;GameOverScreen&quot;</span> Storyboard.TargetProperty=<span>&quot;(UIElement.Opacity)&quot;</span> BeginTime=<span>&quot;00:00:00&quot;</span>&gt;</pre>
<pre><span>   3:</span>         &lt;SplineDoubleKeyFrame KeyTime=<span>&quot;00:00:00&quot;</span> Value=<span>&quot;0&quot;</span>/&gt;</pre>
<pre><span>   4:</span>         &lt;SplineDoubleKeyFrame KeyTime=<span>&quot;00:00:01&quot;</span> Value=<span>&quot;1&quot;</span>/&gt;</pre>
<pre><span>   5:</span>     &lt;/DoubleAnimationUsingKeyFrames&gt;</pre>
<pre><span>   6:</span> &lt;/Storyboard&gt;</pre>
<pre><span>   7:</span> &lt;Storyboard x:Name=<span>&quot;FadeOut&quot;</span> Completed=<span>&quot;FadeOut_Completed&quot;</span>&gt;</pre>
<pre><span>   8:</span>     &lt;DoubleAnimationUsingKeyFrames Storyboard.TargetName=<span>&quot;GameOverScreen&quot;</span> Storyboard.TargetProperty=<span>&quot;(UIElement.Opacity)&quot;</span> BeginTime=<span>&quot;00:00:00&quot;</span>&gt;</pre>
<pre><span>   9:</span>         &lt;SplineDoubleKeyFrame KeyTime=<span>&quot;00:00:00&quot;</span> Value=<span>&quot;1&quot;</span>/&gt;</pre>
<pre><span>  10:</span>         &lt;SplineDoubleKeyFrame KeyTime=<span>&quot;00:00:01&quot;</span> Value=<span>&quot;0&quot;</span>/&gt;</pre>
<pre><span>  11:</span>     &lt;/DoubleAnimationUsingKeyFrames&gt;</pre>
<pre><span>  12:</span> &lt;/Storyboard&gt;</pre>
</div>
</div>
<p><strong>WCF Communication</strong></p>
<p>In the previous section I described a WCF service I created to communicate with and transfer high scores.&nbsp; Below I will show the code within my Silverlight project that calls methods from this WCF service.&nbsp; If you followed the WCF in Silverlight video from
 the Swiss MSDN Team described above you will have created a Service Reference within your project.&nbsp; This reference can access methods and objects within your Application Web Project as shown in the example below.&nbsp;
</p>
<p>The Return High Scores Completed event retrieves High Scores from the WCF service and stores them within the Silverlight project.</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>void</span> _client_ReturnHighScoresCompleted(<span>object</span> sender, MissileCommand.ServiceReference1.ReturnHighScoresCompletedEventArgs e)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     HighScores = e.Result <span>as</span> MissileCommand.ServiceReference1.HighScore;</pre>
<pre><span>   4:</span>     _singleHighScore.Score = <span>&quot;0&quot;</span>;</pre>
<pre><span>   5:</span>     <span>foreach</span> (MissileCommand.ServiceReference1.Scores score <span>in</span> HighScores.Scores)</pre>
<pre><span>   6:</span>     {</pre>
<pre><span>   7:</span>         <span>if</span> (Convert.ToDouble(score.Score) &gt; Convert.ToDouble(_singleHighScore.Score))</pre>
<pre><span>   8:</span>         {</pre>
<pre><span>   9:</span>             _singleHighScore = score;</pre>
<pre><span>  10:</span>         }</pre>
<pre><span>  11:</span>     }</pre>
<pre><span>  12:</span>   </pre>
<pre><span>  13:</span>     SetSingleHighScoreEvent(_singleHighScore, HighScores.GamesPlayed);</pre>
<pre><span>  14:</span>&nbsp; </pre>
<pre><span>  15:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> Private Sub _client_ReturnHighScoresCompleted(ByVal sender As Object, ByVal e As RetroCommandVB.ServiceReference1.ReturnHighScoresCompletedEventArgs)</pre>
<pre><span>   2:</span>     HighScores = e.Result</pre>
<pre><span>   3:</span>     _singleHighScore.Score = <span>&quot;0&quot;</span></pre>
<pre><span>   4:</span>     For Each score As ServiceReference1.Scores In HighScores.Scores</pre>
<pre><span>   5:</span>         If Convert.ToDouble(score.Score) &gt; Convert.ToDouble(_singleHighScore.Score) Then</pre>
<pre><span>   6:</span>             _singleHighScore = score</pre>
<pre><span>   7:</span>         End If</pre>
<pre><span>   8:</span>     Next</pre>
<pre><span>   9:</span>&nbsp; </pre>
<pre><span>  10:</span>     RaiseEvent SetSingleHighScoreEvent(_singleHighScore, HighScores.GamesPlayed)</pre>
<pre><span>  11:</span> End Sub</pre>
</div>
</div>
<p>The method UpdateHighScoresList sends the updated High Scores and count of games played to the WCF Service.</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>public</span> <span>void</span> UpdateHighScoresList(MissileCommand.ServiceReference1.Scores newScore)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     MissileCommand.ServiceReference1.HighScore newHighScoresList = HighScores;</pre>
<pre><span>   4:</span>     List&lt;MissileCommand.ServiceReference1.Scores&gt; scoresList = <span>new</span> List&lt;MissileCommand.ServiceReference1.Scores&gt;();</pre>
<pre><span>   5:</span>      </pre>
<pre><span>   6:</span>     <span>bool</span> newHighScore = <span>false</span>;</pre>
<pre><span>   7:</span>     <span>foreach</span> (MissileCommand.ServiceReference1.Scores score <span>in</span> HighScores.Scores)</pre>
<pre><span>   8:</span>     {</pre>
<pre><span>   9:</span>         <span>if</span> (Convert.ToDouble(newScore.Score) &gt; Convert.ToDouble(score.Score) &amp;&amp; !newHighScore)</pre>
<pre><span>  10:</span>         {</pre>
<pre><span>  11:</span>             scoresList.Add(newScore);</pre>
<pre><span>  12:</span>             scoresList.Add(score);</pre>
<pre><span>  13:</span>             newHighScore = <span>true</span>;</pre>
<pre><span>  14:</span>         }</pre>
<pre><span>  15:</span>         <span>else</span></pre>
<pre><span>  16:</span>         {</pre>
<pre><span>  17:</span>           scoresList.Add(score);</pre>
<pre><span>  18:</span>         }</pre>
<pre><span>  19:</span>     }</pre>
<pre><span>  20:</span>&nbsp; </pre>
<pre><span>  21:</span>     newHighScoresList.GamesPlayed = (Convert.ToDouble(newHighScoresList.GamesPlayed) &#43; 1).ToString();</pre>
<pre><span>  22:</span>     newHighScoresList.Scores[0] = scoresList[0];</pre>
<pre><span>  23:</span>     newHighScoresList.Scores[1] = scoresList[1];</pre>
<pre><span>  24:</span>     newHighScoresList.Scores[2] = scoresList[2];</pre>
<pre><span>  25:</span>     newHighScoresList.Scores[3] = scoresList[3];</pre>
<pre><span>  26:</span>     newHighScoresList.Scores[4] = scoresList[4];</pre>
<pre><span>  27:</span>     newHighScoresList.Scores[5] = scoresList[5];</pre>
<pre><span>  28:</span>     newHighScoresList.Scores[6] = scoresList[6];</pre>
<pre><span>  29:</span>     newHighScoresList.Scores[7] = scoresList[7];</pre>
<pre><span>  30:</span>     newHighScoresList.Scores[8] = scoresList[8];</pre>
<pre><span>  31:</span>     newHighScoresList.Scores[9] = scoresList[9];</pre>
<pre><span>  32:</span>&nbsp; </pre>
<pre><span>  33:</span>     HighScores = newHighScoresList;</pre>
<pre><span>  34:</span>     _client.SaveHighScoresAsync(newHighScoresList);</pre>
<pre><span>  35:</span>    </pre>
<pre><span>  36:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> Public Sub UpdateHighScoresList(ByVal newScore As ServiceReference1.Scores)</pre>
<pre><span>   2:</span>     Dim newHighScoreList As ServiceReference1.HighScores = HighScores()</pre>
<pre><span>   3:</span>     Dim scoresList As List(Of ServiceReference1.Scores) = New List(Of ServiceReference1.Scores)()</pre>
<pre><span>   4:</span>&nbsp; </pre>
<pre><span>   5:</span>     Dim newHighScore As Boolean = False</pre>
<pre><span>   6:</span>&nbsp; </pre>
<pre><span>   7:</span>     For Each score As ServiceReference1.Scores In HighScores.Scores</pre>
<pre><span>   8:</span>         If Convert.ToDouble(newScore.Score) &gt; Convert.ToDouble(score.Score) And Not newHighScore Then</pre>
<pre><span>   9:</span>             scoresList.Add(newScore)</pre>
<pre><span>  10:</span>             scoresList.Add(score)</pre>
<pre><span>  11:</span>             newHighScore = True</pre>
<pre><span>  12:</span>         Else</pre>
<pre><span>  13:</span>             scoresList.Add(score)</pre>
<pre><span>  14:</span>         End If</pre>
<pre><span>  15:</span>     Next</pre>
<pre><span>  16:</span>&nbsp; </pre>
<pre><span>  17:</span>     newHighScoreList.GamesPlayed = (Convert.ToDouble(newHighScoreList.GamesPlayed) &#43; 1).ToString()</pre>
<pre><span>  18:</span>     newHighScoreList.Scores(0) = scoresList(0)</pre>
<pre><span>  19:</span>     newHighScoreList.Scores(1) = scoresList(1)</pre>
<pre><span>  20:</span>     newHighScoreList.Scores(2) = scoresList(2)</pre>
<pre><span>  21:</span>     newHighScoreList.Scores(3) = scoresList(3)</pre>
<pre><span>  22:</span>     newHighScoreList.Scores(4) = scoresList(4)</pre>
<pre><span>  23:</span>     newHighScoreList.Scores(5) = scoresList(5)</pre>
<pre><span>  24:</span>     newHighScoreList.Scores(6) = scoresList(6)</pre>
<pre><span>  25:</span>     newHighScoreList.Scores(7) = scoresList(7)</pre>
<pre><span>  26:</span>     newHighScoreList.Scores(8) = scoresList(8)</pre>
<pre><span>  27:</span>     newHighScoreList.Scores(9) = scoresList(9)</pre>
<pre><span>  28:</span>&nbsp; </pre>
<pre><span>  29:</span>     HighScores = newHighScoreList</pre>
<pre><span>  30:</span>&nbsp; </pre>
<pre><span>  31:</span>     _client.SaveHighScoresAsync(newHighScoreList)</pre>
<pre><span>  32:</span> End Sub</pre>
</div>
</div>
<p><strong>Gaming Loop</strong></p>
<p>Each gaming loop begins at the start of a particular level.&nbsp; The gaming loop ends when the level is complete.&nbsp; This is specified when all enemy missiles within a level are fired.&nbsp;
</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>void</span> LevelBreakScreen_StartLevelEvent()</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     meIntermission.Stop();</pre>
<pre><span>   4:</span>     LayoutRoot.Children.Remove(meIntermission);</pre>
<pre><span>   5:</span>     LevelBreakScreen.Visibility = Visibility.Collapsed;</pre>
<pre><span>   6:</span>     GameLoop.Begin();</pre>
<pre><span>   7:</span>     StartL</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> Sub LevelBreakScreen_StartLevelEvent()</pre>
<pre><span>   2:</span>     meIntermission.Stop()</pre>
<pre><span>   3:</span>     LayoutRoot.Children.Remove(meIntermission)</pre>
<pre><span>   4:</span>     LevelBreakScreen.Visibility = Windows.Visibility.Collapsed</pre>
<pre><span>   5:</span>     GameLoop.Begin()</pre>
<pre><span>   6:</span>     StartLevel(_currentLevel)</pre>
<pre><span>   7:</span> End Sub</pre>
</div>
</div>
<p>The game loop repeats based on a level specified timer until all enemy attack lines have been created and destroyed.&nbsp;
</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>private</span> <span>void</span> GameLoop_Completed(<span>object</span> sender, EventArgs e)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     TimeSpan timeSpan = DateTime.Now - _currentTime;</pre>
<pre><span>   4:</span>     <span>if</span> (timeSpan.Seconds &gt; _timeElapsed)</pre>
<pre><span>   5:</span>     {</pre>
<pre><span>   6:</span>         <span>if</span> (_currentLine &lt; _lineCount - 1)</pre>
<pre><span>   7:</span>         {</pre>
<pre><span>   8:</span>             _currentLine&#43;&#43;;</pre>
<pre><span>   9:</span>             AddLine(_lineCollection[_currentLine]);</pre>
<pre><span>  10:</span>             _currentTime = DateTime.Now;</pre>
<pre><span>  11:</span>         }</pre>
<pre><span>  12:</span>         <span>if</span> (_linesRemoved == _lineCollection.Count)</pre>
<pre><span>  13:</span>         {</pre>
<pre><span>  14:</span>             _isRunning = <span>false</span>;</pre>
<pre><span>  15:</span>&nbsp; </pre>
<pre><span>  16:</span>         }</pre>
<pre><span>  17:</span>&nbsp; </pre>
<pre><span>  18:</span>     }</pre>
<pre><span>  19:</span>&nbsp; </pre>
<pre><span>  20:</span>&nbsp; </pre>
<pre><span>  21:</span>     <span>if</span> (_isRunning)</pre>
<pre><span>  22:</span>     {</pre>
<pre><span>  23:</span>         GameLoop.Begin();</pre>
<pre><span>  24:</span>     }</pre>
<pre><span>  25:</span>&nbsp; </pre>
<pre><span>  26:</span>&nbsp; </pre>
<pre><span>  27:</span>&nbsp; </pre>
<pre><span>  28:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> Private Sub GameLoop_Completed(ByVal sender As Object, ByVal e As EventArgs)</pre>
<pre><span>   2:</span>     Dim timeSpan As TimeSpan = DateTime.Now - _currentTime</pre>
<pre><span>   3:</span>&nbsp; </pre>
<pre><span>   4:</span>     If timeSpan.Seconds &gt; _timeElapsed Then</pre>
<pre><span>   5:</span>         If _currentLine &lt; _lineCount - 1 Then</pre>
<pre><span>   6:</span>             _currentLine = _currentLine &#43; 1</pre>
<pre><span>   7:</span>             AddLine(_lineCollection(_currentLine))</pre>
<pre><span>   8:</span>             _currentTime = DateTime.Now</pre>
<pre><span>   9:</span>         End If</pre>
<pre><span>  10:</span>         If _linesRemoved = _lineCollection.Count Then</pre>
<pre><span>  11:</span>             _isRunning = False</pre>
<pre><span>  12:</span>         End If</pre>
<pre><span>  13:</span>     End If</pre>
<pre><span>  14:</span>&nbsp; </pre>
<pre><span>  15:</span>     If _isRunning Then</pre>
<pre><span>  16:</span>         GameLoop.Begin()</pre>
<pre><span>  17:</span>     End If</pre>
<pre><span>  18:</span> End Sub</pre>
</div>
</div>
<p><strong>Missile Attack and Defense Lines</strong></p>
<p>Missile attack lines are created during game play.&nbsp; At the start of a level, instances of all the attack lines within the level are created.&nbsp; These lines have parameters passed in that determine the starting point, angle, and speed of the attack line.&nbsp; These
 lines are drawn to the screen during the game loop in a method called AddLine (see code snippet above).&nbsp;
</p>
<p>Missile defense lines are created when a user clicks either <strong>a, s, </strong>
or <strong>d</strong> on the keyboard.&nbsp; The defensive lines are handled in the same manor as attack lines except the end point and angle are determined by the mouse point position at the time of firing.&nbsp; I also added some interesting sound effects for user
 enjoyment.&nbsp; </p>
<p><strong>Collision Detection</strong></p>
<p>Collision detection was probably the most enjoyable part of developing this game.&nbsp; The reason for this is that in Silverlight 2.0 beta there is a nice little method called HitTest that analyzes two objects and determines if they collide.&nbsp; Each line has its
 own storyboard which continuously looks for collisions with other objects.&nbsp; When a line collides with an object that information is stored for future analysis and the line is destroyed.&nbsp; Attack lines run until they collide with an object such as a cloud, city,
 missile base, or the ground.&nbsp; Defensive lines have a fixed destination and when they reach that destination a cloud is created.&nbsp; The cloud has an area and if any attack lines collide with that area they of course are destroyed.&nbsp; The cloud itself has a time
 period duration in which enemy lines can collide.&nbsp; It will eventually fade away.&nbsp; The majority of user interaction is based on this code.</p>
<p><strong>C#</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>private</span> <span>void</span> missileLineStoryboard_Completed(<span>object</span> sender, EventArgs e)</pre>
<pre><span>   2:</span> {</pre>
<pre><span>   3:</span>     <span>//Check for collision</span></pre>
<pre><span>   4:</span>     Page page = (<span>this</span>.Parent <span>as</span> Grid).Parent <span>as</span> Page;</pre>
<pre><span>   5:</span>&nbsp; </pre>
<pre><span>   6:</span>     <span>if</span> (!IsMissile)</pre>
<pre><span>   7:</span>     {</pre>
<pre><span>   8:</span>         <span>//check all bottom grid rectangles</span></pre>
<pre><span>   9:</span>         <span>if</span> (CheckCollision(page.recBottom, misLine, page.recBottom.Name) ||</pre>
<pre><span>  10:</span>             CheckCollision(page.recLeft, misLine, page.recLeft.Name) ||</pre>
<pre><span>  11:</span>             CheckCollision(page.recCenter, misLine, page.recCenter.Name ) ||</pre>
<pre><span>  12:</span>             CheckCollision(page.recRight, misLine, page.recRight.Name) ||</pre>
<pre><span>  13:</span>             CheckCollision(page.myCloud.recCloud, misLine, page.myCloud.Name) ||</pre>
<pre><span>  14:</span>             CheckCollision(page.City1.recCity, misLine, page.City1.Name) ||</pre>
<pre><span>  15:</span>             CheckCollision(page.City2.recCity, misLine, page.City2.Name) ||</pre>
<pre><span>  16:</span>             CheckCollision(page.City3.recCity, misLine, page.City3.Name) ||</pre>
<pre><span>  17:</span>             CheckCollision(page.City4.recCity, misLine, page.City4.Name) ||</pre>
<pre><span>  18:</span>             CheckCollision(page.City5.recCity, misLine, page.City5.Name) ||</pre>
<pre><span>  19:</span>             CheckCollision(page.City6.recCity, misLine, page.City6.Name))</pre>
<pre><span>  20:</span>         {</pre>
<pre><span>  21:</span>             _isRunning = <span>false</span>;</pre>
<pre><span>  22:</span>             DestroyLineEvent(<span>this</span>);        </pre>
<pre><span>  23:</span>         }</pre>
<pre><span>  24:</span>&nbsp; </pre>
<pre><span>  25:</span>         <span>if</span> (_isRunning)</pre>
<pre><span>  26:</span>         {</pre>
<pre><span>  27:</span>             missileLineAnimationX.From = misLine.X2;</pre>
<pre><span>  28:</span>             missileLineAnimationY.From = misLine.Y2;</pre>
<pre><span>  29:</span>             missileLineStoryboard.Duration = _lineDuration;</pre>
<pre><span>  30:</span>             misLine.Y2 = _currentY2Position &#43; Y2Increment;</pre>
<pre><span>  31:</span>             misLine.X2 = ((misLine.Y2 - misLine.Y1) / Math.Tan(_angle)) &#43; misLine.X1;</pre>
<pre><span>  32:</span>             missileLineAnimationX.To = misLine.X2;</pre>
<pre><span>  33:</span>             missileLineAnimationY.To = misLine.Y2;</pre>
<pre><span>  34:</span>             _currentY2Position = misLine.Y2;</pre>
<pre><span>  35:</span>&nbsp; </pre>
<pre><span>  36:</span>             missileLineStoryboard.Begin();</pre>
<pre><span>  37:</span>         }</pre>
<pre><span>  38:</span>     }</pre>
<pre><span>  39:</span>     <span>else</span></pre>
<pre><span>  40:</span>     {</pre>
<pre><span>  41:</span>         _isRunning = <span>false</span>;</pre>
<pre><span>  42:</span>         DestroyLineEvent(<span>this</span>);</pre>
<pre><span>  43:</span>     }</pre>
<pre><span>  44:</span> }</pre>
<pre><span>  45:</span>&nbsp; </pre>
<pre><span>  46:</span> <span>private</span> <span>bool</span> CheckCollision(Rectangle control1, Line control2, <span>string</span> control1Name)</pre>
<pre><span>  47:</span> {</pre>
<pre><span>  48:</span>     <span>bool</span> bCollision = <span>false</span>;</pre>
<pre><span>  49:</span>&nbsp; </pre>
<pre><span>  50:</span>     <span>//check for previous cloud location, if not visible ignore hit</span></pre>
<pre><span>  51:</span>    </pre>
<pre><span>  52:</span>     Point ptCheck = <span>new</span> Point();</pre>
<pre><span>  53:</span>     ptCheck.X = control2.X2;</pre>
<pre><span>  54:</span>     ptCheck.Y = control2.Y2;</pre>
<pre><span>  55:</span>     List&lt;UIElement&gt; hits1 = (List&lt;UIElement&gt;)control1.HitTest(ptCheck);</pre>
<pre><span>  56:</span>     <span>if</span> (hits1.Count &gt; 0)</pre>
<pre><span>  57:</span>     {</pre>
<pre><span>  58:</span>        </pre>
<pre><span>  59:</span>         ControlName = control1Name;</pre>
<pre><span>  60:</span>         bCollision = <span>true</span>;</pre>
<pre><span>  61:</span>     }</pre>
<pre><span>  62:</span>     <span>return</span> bCollision;</pre>
<pre><span>  63:</span> }</pre>
</div>
</div>
<p><strong>VB</strong></p>
<div>
<div>
<pre><span>   1:</span> <span>Private</span> <span>Sub</span> missileLineStoryboard_Completed(<span>ByVal</span> sender <span>As</span> System.<span>Object</span>, <span>ByVal</span> e <span>As</span> System.EventArgs)</pre>
<pre><span>   2:</span>     <span>Dim</span> page <span>As</span> Page = <span>DirectCast</span>(<span>DirectCast</span>(<span>Me</span>.Parent, Grid).Parent, Page)</pre>
<pre><span>   3:</span>&nbsp; </pre>
<pre><span>   4:</span>     <span>If</span> <span>Not</span> IsMissile <span>Then</span></pre>
<pre><span>   5:</span>         <span>If</span> CheckCollision(page.recBottom, misLine, page.recBottom.Name) <span>Or</span> _</pre>
<pre><span>   6:</span>             CheckCollision(page.recLeft, misLine, page.recLeft.Name) <span>Or</span> _</pre>
<pre><span>   7:</span>             CheckCollision(page.recCenter, misLine, page.recCenter.Name) <span>Or</span> _</pre>
<pre><span>   8:</span>             CheckCollision(page.recRight, misLine, page.recRight.Name) <span>Or</span> _</pre>
<pre><span>   9:</span>             CheckCollision(page.myCloud.recCloud, misLine, page.myCloud.Name) <span>Or</span> _</pre>
<pre><span>  10:</span>             CheckCollision(page.City1.recCity, misLine, page.City1.Name) <span>Or</span> _</pre>
<pre><span>  11:</span>             CheckCollision(page.City2.recCity, misLine, page.City2.Name) <span>Or</span> _</pre>
<pre><span>  12:</span>             CheckCollision(page.City3.recCity, misLine, page.City3.Name) <span>Or</span> _</pre>
<pre><span>  13:</span>             CheckCollision(page.City4.recCity, misLine, page.City4.Name) <span>Or</span> _</pre>
<pre><span>  14:</span>             CheckCollision(page.City5.recCity, misLine, page.City5.Name) <span>Or</span> _</pre>
<pre><span>  15:</span>             CheckCollision(page.City6.recCity, misLine, page.City6.Name) <span>Then</span></pre>
<pre><span>  16:</span>&nbsp; </pre>
<pre><span>  17:</span>             _isRunning = <span>False</span></pre>
<pre><span>  18:</span>             <span>RaiseEvent</span> DestroyLineEvent(<span>Me</span>)</pre>
<pre><span>  19:</span>&nbsp; </pre>
<pre><span>  20:</span>         <span>End</span> <span>If</span></pre>
<pre><span>  21:</span>&nbsp; </pre>
<pre><span>  22:</span>         <span>If</span> _isRunning <span>Then</span></pre>
<pre><span>  23:</span>             missileLineAnimationX.From = misLine.X2</pre>
<pre><span>  24:</span>             missileLineAnimationY.From = misLine.Y2</pre>
<pre><span>  25:</span>             missileLineStoryboard.Duration = _lineDuration</pre>
<pre><span>  26:</span>             misLine.Y2 = _currentY2Position &#43; Y2Increment</pre>
<pre><span>  27:</span>             misLine.X2 = ((misLine.Y2 - misLine.Y1) / Math.Tan(_angle)) &#43; misLine.X1</pre>
<pre><span>  28:</span>             missileLineAnimationX.<span>To</span> = misLine.X2</pre>
<pre><span>  29:</span>             missileLineAnimationY.<span>To</span> = misLine.Y2</pre>
<pre><span>  30:</span>             _currentY2Position = misLine.Y2</pre>
<pre><span>  31:</span>&nbsp; </pre>
<pre><span>  32:</span>             missileLineStoryboard.Begin()</pre>
<pre><span>  33:</span>         <span>End</span> <span>If</span></pre>
<pre><span>  34:</span>     <span>Else</span></pre>
<pre><span>  35:</span>         _isRunning = <span>False</span></pre>
<pre><span>  36:</span>         <span>RaiseEvent</span> DestroyLineEvent(<span>Me</span>)</pre>
<pre><span>  37:</span>     <span>End</span> <span>If</span></pre>
<pre><span>  38:</span> <span>End</span> <span>Sub</span></pre>
<pre><span>  39:</span>&nbsp; </pre>
<pre><span>  40:</span> <span>Private</span> <span>Function</span> CheckCollision(<span>ByVal</span> control1 <span>As</span> Rectangle, <span>ByVal</span> control2 <span>As</span> Line, <span>ByVal</span> control1Name <span>As</span> <span>String</span>) <span>As</span> <span>Boolean</span></pre>
<pre><span>  41:</span>     <span>Dim</span> bCollision <span>As</span> <span>Boolean</span> = <span>False</span></pre>
<pre><span>  42:</span>&nbsp; </pre>
<pre><span>  43:</span>     <span>Dim</span> ptCheck <span>As</span> Point = <span>New</span> Point()</pre>
<pre><span>  44:</span>     ptCheck.X = control2.X2</pre>
<pre><span>  45:</span>     ptCheck.Y = control2.Y2</pre>
<pre><span>  46:</span>     <span>Dim</span> hits1 <span>As</span> List(Of UIElement) = <span>DirectCast</span>(control1.HitTest(ptCheck), List(Of UIElement))</pre>
<pre><span>  47:</span>     <span>If</span> hits1.Count &gt; 0 <span>Then</span></pre>
<pre><span>  48:</span>         ControlName = control1Name</pre>
<pre><span>  49:</span>         bCollision = <span>True</span></pre>
<pre><span>  50:</span>     <span>End</span> <span>If</span></pre>
<pre><span>  51:</span>&nbsp; </pre>
<pre><span>  52:</span>     <span>Return</span> bCollision</pre>
<pre><span>  53:</span> <span>End</span> Function</pre>
</div>
</div>
<p><strong>Scoring and Game Play</strong></p>
<p>Scoring for game play was kind of fun to create.&nbsp; Default scoring involves points for destroyed attack lines, remaining missiles and remaining cities.&nbsp; If you destroy multiple attacks lines with one missile shot you will get extra points.&nbsp; So basically scoring
 is not fixed, you have the ability to get a different score each time depending on how you destroy attack lines.&nbsp; As levels progress, the game play gets harder.&nbsp; At first this game is meant to be easy, but in the higher levels it can get quite difficult.&nbsp;
 The last level, level 10, is extremely hard.&nbsp; Kudos to anyone who can beat it!</p>
<h3>Conclusion</h3>
<p>The finished product is not only something I can use as a fantastic learning experience, but is something I can enjoy playing myself.&nbsp; It has definitely surpassed my goals and expectations.&nbsp; I used new technologies such as WCF and Silverlight and created
 a game that is fun.&nbsp; I knew this game was successful when my fellow co-workers spent hours trying to get the highest score during my debugging phase.&nbsp; Thanks Spencer and Justin!&nbsp; I've already started thinking of my next gaming application!</p>
<p>If you have any questions about this solution or have suggestions for improvement, feel free to contact me at
<a href="mailto:gary.farr@claritycon.com">gary.farr@claritycon.com</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Gary-Farr/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:9e4aef730d49495484589e7600cf5aab">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/RetroCommand</comments>
      <itunes:summary>
In this article, I will discuss how I have built RetroCommand, a Silverlight 2.0 Beta 1 version of a classic arcade game (play here).&amp;nbsp; I will explain how I used Expression
 Blend along with some of the new and interesting Silverlight 2.0 and WCF features to create a fun and entertaining game that will have us all thinking it was 1980 again!
 
I have recently updated the game for Silverlight 2.0 Beta 2.&amp;nbsp; If you would like to access that version of the game you can (here).&amp;nbsp;
 
Gary Farr 
Coding4Fun at Clarity&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
 
Difficulty: Intermediate 
Time Required: Greater than 10 hours 
Cost: Free 
Software: Visual Studio 2008,
Silverlight 2.0 Beta 1, 
Expressions Blend 2.5 March Preview&amp;nbsp; 
Hardware: 
Download: 
Download 

 
Introduction
Ah video games!&amp;nbsp; Growing up I&#39;ve played an array of gaming consoles.&amp;nbsp; I started with the Atari 2600 and followed with Sega, Sega Genesis, Playstation, Dreamcast, Playstation 2, Gamecube, XBOX, and now the Wii.&amp;nbsp; This of course includes countless hours of
 computer and online gaming.&amp;nbsp; Well, I have recently been developing WPF applications and wanted to do something fun with Silverlight since this technology opens so many new doors for web development on the Microsoft platform.&amp;nbsp; Being an avid game player, web
 based games struck a chord with me and I quickly decided my first Silverlight app would be a game.&amp;nbsp; I started researching.&amp;nbsp;
 
There is a lot of information out there about game programming in Silverlight.&amp;nbsp;
Mike Snow has some great introductory blog posts.&amp;nbsp;
Silverlight Games 101 is also a good source for game development.&amp;nbsp; Of course
Silverlight.Net has been posting some great gaming examples since the release of Silverlight 1.0.&amp;nbsp; I also have to give some props to my co-worker Justin Petersen, whose
Silverlight 8-Ball game helped me actually get started.&amp;nbsp;
 
Once the research began, the next step was deciding what video game I should write.</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/RetroCommand</link>
      <pubDate>Mon, 09 Jun 2008 12:01:21 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/RetroCommand</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8586040_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8586040_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Gary Farr </dc:creator>
      <itunes:author>Gary Farr </itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/RetroCommand/RSS</wfw:commentRss>
      <category>Games</category>
      <category>Silverlight</category>
      <category>Classic</category>
    </item>    
</channel>
</rss>