<?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/BrianPeek/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/BrianPeek/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/BrianPeek/Posts</link>
    <language>en</language>
    <pubDate>Wed, 22 May 2013 04:54:50 GMT</pubDate>
    <lastBuildDate>Wed, 22 May 2013 04:54:50 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>50</c9:totalResults>
    <c9:pageCount>2</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Channel 9 turns 9!</title>
      <description><![CDATA[<p><span>From our humble beginnings as a website built with alpha quality forum technologies that we stitched together with creative code and a lot of love, and our videos were made by a few dudes roaming the halls of Microsoft with a cheap camcorder – look at us now. Channel 9 streams live events to 100,000s of people around the world, we have a state of the art recording studio, we do C9 Live at events around the world bringing you directly into the conversation with Microsoft folks in real time. Today, much of our content is created from folks around the company. Channel 9 is THE place to watch MS events on demand and to learn about our technologies from the people who make them – people are the lifeblood of software and technology. Channel 9 is people! <br><br>Today marks 9 years of 9. It's a very special day. We are especially humbled and honored to still be around given the change rate of the web. We thank all past, present and future Niners for the excellent conversations, arguments, debates, entertainment, and camaraderie. &nbsp;9 Years of 9. That rolls so nicely off the tongue.&nbsp; Here's to 9 more.</span></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:5982f907684740249cfea182000a5272">]]></description>
      <comments>http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9</comments>
      <itunes:summary>From our humble beginnings as a website built with alpha quality forum technologies that we stitched together with creative code and a lot of love, and our videos were made by a few dudes roaming the halls of Microsoft with a cheap camcorder – look at us now. Channel 9 streams live events to 100,000s of people around the world, we have a state of the art recording studio, we do C9 Live at events around the world bringing you directly into the conversation with Microsoft folks in real time. Today, much of our content is created from folks around the company. Channel 9 is THE place to watch MS events on demand and to learn about our technologies from the people who make them – people are the lifeblood of software and technology. Channel 9 is people! Today marks 9 years of 9. It&#39;s a very special day. We are especially humbled and honored to still be around given the change rate of the web. We thank all past, present and future Niners for the excellent conversations, arguments, debates, entertainment, and camaraderie. &amp;nbsp;9 Years of 9. That rolls so nicely off the tongue.&amp;nbsp; Here&#39;s to 9 more. </itunes:summary>
      <itunes:duration>562</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9</link>
      <pubDate>Fri, 15 Mar 2013 13:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.mp3" expression="full" duration="562" fileSize="9007482" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.mp4" expression="full" duration="562" fileSize="52588716" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.webm" expression="full" duration="562" fileSize="21935504" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.wma" expression="full" duration="562" fileSize="4559095" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.wmv" expression="full" duration="562" fileSize="62278697" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_high.mp4" expression="full" duration="562" fileSize="114186491" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_mid.mp4" expression="full" duration="562" fileSize="79671024" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9_Source.wmv" expression="full" duration="562" fileSize="313490493" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.ism/manifest" expression="full" duration="562" fileSize="8462" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/9826/a8204213-5530-4743-90d2-e3e3b58b9826/Channel9turns9.wmv" length="62278697" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Charles, Clint Rutkas, Dan Fernandez, Duncan Mackenzie, Jeff Sandquist, Larry Larsen, Laura Foy, Golnaz, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Charles, Clint Rutkas, Dan Fernandez, Duncan Mackenzie, Jeff Sandquist, Larry Larsen, Laura Foy, Golnaz, Rick Barraza</itunes:author>
      <slash:comments>48</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/C9Team/Channel-9-turns-9/RSS</wfw:commentRss>
    </item>
  <item>
      <title>TWC9: Update 2 CTP4 Go Live, Office 2013 Dev Tools, Kinect code and more</title>
      <description><![CDATA[<p>This week on Channel 9, Dan and Brian Peek discuss the week's top developer news, including;</p><ul><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=42s">[0:42]</a>&nbsp;<a href="http://blogs.msdn.com/b/visualstudioalm/archive/2013/03/04/march-ctp-of-visual-studio-update-2.aspx">March CTP (“CTP4”) of Visual Studio Update 2 now available</a> (Charles Sterling) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=2m7s">[2:07]</a>&nbsp;<a href="http://blogs.msdn.com/b/somasegar/archive/2013/03/04/now-available-office-developer-tools-for-visual-studio-2012.aspx">Now Available: Office Developer Tools for Visual Studio 2012</a> (S. Somasegar) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=3m33s">[3:33]</a>&nbsp;<a href="http://blogs.msdn.com/b/visualstudioalm/archive/2013/03/07/core-ignorecase-corruption-issue-fixed-in-visual-studio-tools-for-git-0-8-0-0.aspx" target="_blank">Visual Studio Tools for Git 0.8.0.0</a> (Andy Lewis) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=4m49s">[4:49]</a>&nbsp;<a href="http://blogs.msdn.com/b/lightswitch/archive/2013/03/04/announcing-a-new-preview-of-the-lightswitch-html-client.aspx">Announcing a New Preview of the LightSwitch HTML Client</a> </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=6m7s">[6:07]</a>&nbsp;<a href="http://blogs.msdn.com/b/bethmassi/archive/2013/03/04/getting-started-with-lightswitch-in-visual-studio-2012-update-2-ctp4.aspx">Getting Started with LightSwitch in Visual Studio 2012 Update 2 CTP4</a> (Beth Massi) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=6m40s">[6:40]</a>&nbsp;<a href="http://blog.markedup.com/2013/03/metroappsite-free-open-source-metro-style-website-templates-for-your-windows-store-apps/">MetroAppSite: Free, Open Source Metro-Style Website Templates for Your Windows Store Apps</a> (Aaron Stannard) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=7m35s">[7:35]</a>&nbsp;<a href="http://www.silverlightshow.net/video/Applied-MVVM-in-Win8-Webinar.aspx">Recording of Webinar 'Applied MVVM in Windows 8 apps' by Gill Cleeren</a> (Gill Cleeren) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=9m1s">[9:01]</a>&nbsp;<a href="http://www.silverlightshow.net/items/Advanced-MVVM-concepts-using-Contoso-Cookbook-An-analysis-of-a-complete-MVVM-application-Part-1.aspx">Advanced MVVM concepts using Contoso Cookbook: An analysis of a complete MVVM application: Part 1</a> (Gill Cleeren) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=9m44s">[9:44]</a>&nbsp;<a href="http://blogs.msdn.com/b/k4wdev/archive/2013/03/06/easy-access-to-kinect-for-windows-sample-code.aspx">Easy Access to Kinect for Windows Sample Code</a> (Ben Lower) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=10m34s">[10:34]</a>&nbsp;<a href="http://sol.gfxile.net/interpolation/index.html" target="_blank">Interpolation Tricks</a> </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Dan's Pick of the Week: <a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=12m6s">[12:06]</a>&nbsp;<a href="http://unity3d.com/beta/windowsstoreapps" target="_blank">Unity Windows Store apps open beta</a>, and <a href="http://channel9.msdn.com/Events/Windows-Camp/Building-Windows-Games-with-Unity">Channel 9 Live event</a>! </li><li>Brian's Pick of the Week: <a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-March-8-2013#time=12m52s">[12:52]</a>&nbsp;<a href="http://channel9.msdn.com/coding4fun/articles/Pano-Head" target="_blank">Panoramic Camera Head</a> </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:b588fc5964e74c6b9aeba17a0173c0e6">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-8-2013</comments>
      <itunes:summary>This week on Channel 9, Dan and Brian Peek discuss the week&#39;s top developer news, including; [0:42]&amp;nbsp;March CTP (“CTP4”) of Visual Studio Update 2 now available (Charles Sterling) [2:07]&amp;nbsp;Now Available: Office Developer Tools for Visual Studio 2012 (S. Somasegar) [3:33]&amp;nbsp;Visual Studio Tools for Git 0.8.0.0 (Andy Lewis) [4:49]&amp;nbsp;Announcing a New Preview of the LightSwitch HTML Client [6:07]&amp;nbsp;Getting Started with LightSwitch in Visual Studio 2012 Update 2 CTP4 (Beth Massi) [6:40]&amp;nbsp;MetroAppSite: Free, Open Source Metro-Style Website Templates for Your Windows Store Apps (Aaron Stannard) [7:35]&amp;nbsp;Recording of Webinar &#39;Applied MVVM in Windows 8 apps&#39; by Gill Cleeren (Gill Cleeren) [9:01]&amp;nbsp;Advanced MVVM concepts using Contoso Cookbook: An analysis of a complete MVVM application: Part 1 (Gill Cleeren) [9:44]&amp;nbsp;Easy Access to Kinect for Windows Sample Code (Ben Lower) [10:34]&amp;nbsp;Interpolation Tricks Picks of the Week! Dan&#39;s Pick of the Week: [12:06]&amp;nbsp;Unity Windows Store apps open beta, and Channel 9 Live event! Brian&#39;s Pick of the Week: [12:52]&amp;nbsp;Panoramic Camera Head </itunes:summary>
      <itunes:duration>859</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-8-2013</link>
      <pubDate>Sat, 09 Mar 2013 19:20:42 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-8-2013</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.mp3" expression="full" duration="859" fileSize="13750855" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.mp4" expression="full" duration="859" fileSize="81450103" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.webm" expression="full" duration="859" fileSize="32160240" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.wma" expression="full" duration="859" fileSize="6956287" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.wmv" expression="full" duration="859" fileSize="60123143" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308_high.mp4" expression="full" duration="859" fileSize="178959348" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308_mid.mp4" expression="full" duration="859" fileSize="124929609" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308_Source.wmv" expression="full" duration="859" fileSize="175685144" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.ism/manifest" expression="full" duration="859" fileSize="6036" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/2797/75c198ec-2cd3-4516-b772-03b2d9682797/TWC920130308.wmv" length="60123143" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Dan Fernandez, Greg Duncan</dc:creator>
      <itunes:author>Brian Peek, Dan Fernandez, Greg Duncan</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-March-8-2013/RSS</wfw:commentRss>
      <category>ALM</category>
      <category>Kinect</category>
      <category>LightSwitch</category>
      <category>MVVM</category>
      <category>Kinect SDK</category>
      <category>Visual Studio 2012</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 12 - Conclusions</title>
      <description><![CDATA[<h3>Project Conclusions</h3><p>Developing FallFury was a fun and educational activity. Besides the fact that I got to work with an amazing team of people who were willing to assist me with the testing and development, I learned some important points about the development process as a whole and have outlined them in this article.&nbsp; Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion">http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Go Outside Your Comfort Zone</h4><p>This past summer, I decided to tackle a new challenge—game development. Never before had I built a game from the ground up. Moreover, as I could already find my way around C# code, I decided that I wanted to make C&#43;&#43; the language of choice, and so worked with DirectX instead of XNA. Additionally, the project needed to be constructed with Windows 8 as the target platform and I’d have to rely on the WinRT stack.</p><p>The concepts were new to me, but I figured that learning about a new platform and a new language would be more interesting than sticking to my comfort zone. Through FallFury I extended my knowledge about pointers, trigonometry, how DirectX handles a lot of the graphics legwork, and how to write HLSL shaders.</p><p>It was a challenging but very rewarding experience.</p><h4>Communicate</h4><p>The most important part of any project is communication. There are always people who know more than you in one field or another, so don't hesitate to reach out to other developers and ask questions. Your code is not perfect, so talk about best practices used in production and how you can improve on what you already have—communication should not be limited to your team, floor, or even building.</p><p>One bonus of my experience at Microsoft was discovering that a lot of developers, when not in a meeting or in the middle of an important assignment, are more than happy to help a fellow employee with a piece of advice or some code review.</p><h4>Plan the Small Details</h4><p>Before you even touch the keyboard to write your first line of code, outline the components of your application and have a general idea of how you’ll implement those components as well as how they’ll interact with each other. It is tempting to start coding and then add or modify features, but doing so will create more problems than it will solve.</p><h4>Build Small Prototypes</h4><p>FallFury is a complex project composed out of blocks such as:</p><ul><li>XML level/metadata reader and writer </li><li>The Share and Settings charm components </li><li>SpriteBatch sub-system </li><li>Level renderer </li><li>Screen sub-system </li><li>Menu interaction sub-system </li></ul><p>Each block is responsible for its own set of tasks and each can be individually tested with either mocked data or a loose connection to the existing codebase. The necessity for small prototypes comes from individual requirements tied to the platform and possible integration scenarios. For example, when I began development, I created a non-hybrid DirectX project, which meant that if I needed to introduce XAML integration, I had to rewrite small parts of my swap chain preparation stack as well as work with a lot of XAML content in the code-behind. The Settings charm integration heavily relied on XAML, and I would have had to write the popup and control-related code in C#.</p><p>Obviously, that was not an option, so I created a hybrid project instead and ported most of my code into the new solution. Lesson learned here: prototype—and prototype early—in order to make sure that what you plan to implement will be implemented in an efficient manner.</p><h4>Test Often, Test with Other People</h4><p>When working on an application, it is important to understand the needs and expectations of your target audience, and a big part of this is making sure that the application provides a way for the user to easily learn about an action without a helper booklet. The menu system is a good example of this in FallFury. As I was designing the buttons on my screens, I tried to implement the approach used in games such as Dance Central—the user simply slides the button-panel and it takes him to the screen that was linked to that specific button. However, as I was testing the application with the local development crowd, I noticed a pattern—people were attempting to simply tap the button instead of sliding it. To avoid this confusion, I added a pulsating arrow on the right side of the button in order to highlight the fact that the button should be displaced in order to be activated.</p><p>The XML level loading system is another example of how secondary testing improved FallFury. Initial element positioning relied on a given level length, as well as on a ration-based placement. For example, if I wanted to put a button in the middle of the screen, I could position it with a value, such as .5. The level loader would then translate this value relative to the screen size. Rick Barraza was creating some test levels when he notified me about a big flaw—as the level extended, some elements were mis-positioned by a large margin compared to the original intended location. This was because when a level length was reset, the ratio was applied on a larger/smaller value, and some elements would therefore overlap. Ultimately, I rewrote the level structure to rely on pixel values, and designed the level-length to calculate automatically based on the included elements and their size.</p><h4>Test on Different Hardware</h4><p>FallFury started with portable hardware in mind. Its original design targeted Windows 8 tablet devices, though it was later decided that the project should support desktop machines as well. That automatically added thousands of possible hardware combinations on which the game might potentially run. Here are just some of the test machines we got to use:</p><ul><li>Samsung Series 7 Slate </li><li>ARM Developer Tablet (Microsoft Surface) </li><li><a href="http://www.asus.com/Eee/Eee_Pad/Eee_Slate_EP121/">ASUS EP121 Slate</a> </li></ul><p>Each of these machines came with its own specific conditions that had to be accommodated. While Samsung Series 7 Slate featured an accelerometer, at the time of development the ASUS EP121 tablet did not have Windows 8 drivers for its sensor. When I sideloaded the game, I noticed that I could no longer control the character the way I wanted to. Also, though FallFury has keyboard controls, I had to develop controls for machines without keyboards. This is why I came up with the concept of touch-based, on-screen controls.</p><p>Moving on to the ARM device, first and foremost I noticed that my shader configurations were not compatible with the platform capabilities. All my testing was done on a machine that supported DirectX Feature Level 10, which was not the case for a low-power ARM machine that supports DirectX Feature Level 9.1. I had to work with some MSDN samples to find a way to properly modify the required shaders so they would work on Windows RT. ARM devices are built with battery life in mind. Therefore, their capabilities are reduced compared to those of a full-sized Windows tablet. This had an impact on the general game performance—some parts of the game, such as particle rendering, were working fine on a desktop machine, but were quite laggy on the ARM tablet. Knowing the possible source of the problem, I had to optimize the particle storage and rendering stack to ensure they didn’t affect the user experience on Windows RT hardware.</p><h4>There Is Never Enough Time - Learn To Cut</h4><p>When I started planning FallFury, I worked up a huge list of features. As the deadline approached, however, I noticed that I somewhat underestimated the allocated project time—a lot of time was spent on testing and eliminating bugs in existing features. That was the point at which I had to cut my feature set.</p><p>When designing the feature list for your app, make sure that you have a clear vision of which features get the priority and which can be cut if necessary. For example, FallFury was originally planned to be a multiplayer game. Although it was tempting to start working on it as such from the very beginning, I knew that it wasn’t a core feature and that it wouldn’t necessarily affect the general play experience on release day. Ultimately, multiplayer capability was dropped from initial development along with a number of other not-immediately-integral features.</p><h4>Expect the Unexpected</h4><p>When allocating time for the project, anticipate situations that might derail the process and cause a delay in the planned delivery date. It is easy to estimate that creating an accelerometer-based motion system will take you a day or two, but you also need to allow for the potential possibility of your code not working as expected, hardware accidents, natural disasters, etc. Doing so will help you focus on the right features at the right time while diminishing the risk of missing the deadline.</p><h4>Platform Samples Are the Best Documentation - Learn to Read Others’ Code</h4><p>While building the core of FallFury, I leveraged multiple features that hadn’t yet become mainstream among Windows developers. Therefore, the documentation was scarce and in some instances the only help I could get was internal. Luckily, Microsoft bundled hundreds of samples that demonstrate what the new platform can do. A lot of the development approaches gained during my internship were learned from looking at the official, publicly released sample code. The lesson here: if it's not on MSDN or blogs, check the official developer samples. For example, I used the <a href="http://code.msdn.microsoft.com/windowsapps/Direct3D-sprite-sample-97ae6262">DirectX sprite drawing sample</a> to see how to build a proper sprite rendering mechanism with behavior similar to the one available in XNA.</p><h4>Atomic Commits</h4><p>When I started, source control wasn’t new to me, but there were proper usage practices that I didn’t apply before the internship. One of them is atomic commits, which I learned from <a href="https://twitter.com/ClintRutkas">Clint Rutkas</a>.</p><p>With every new addition to the application, chances are something might go wrong. It could be a faulty third-party assembly, a misplaced class, or a broken reference that brings down the entire solution. If the commits include longer time intervals, for example, you will ultimately have to roll back to a build without a lot of the new functionality. Using atomic commits, however, you’ll be able to avoid unnecessary, redundant work in the case that something goes wrong during development.</p><h4>A Non-standard Approach Is Not Necessarily a Bad Approach</h4><p>For loading high scores, I needed the UI layout to display the registered items. To do so, I had could either use data binding or write a simple routine that would generate XAML items on the fly in the code-behind. Data binding is a pretty common practice among XAML developers, so my initial thought was to use that, but I would have had to create a C&#43;&#43; binding harness in addition to the existing data retrieval code. The second approach was much cleaner because it didn’t require me to rewrite or add much code. The lesson here: pick the best approach for the job and don’t blindly follow programming trends.</p><h4>Focus on the User Experience</h4><p>At the end of the day, the user doesn’t care whether you wrote the application in native DirectX or XNA, whether you applied the MVVM pattern, or whether you have easily readable code. The user cares about having a great time while playing the game, regardless of its backbone. It’s your goal as a developer to deliver that user experience and ensure that the user feels comfortable with the product. This means that the development cycle goes beyond simply writing code. In FallFury, levels are dynamic, which means the source code doesn’t necessarily need to be modified in order to create a different playable experience. But that experience matters in any case, and level design is a huge part of FallFury’s final product. Users need to be immersed in the game world, so levels must be planned in such as way that the user returns to the game and doesn’t abandon it after a couple of lost rounds.</p><h4>Conclusion</h4><p>FallFury was my first major project that I wrote almost entirely in C&#43;&#43;, targeting the newly released Windows 8 operating system. Although the development process was challenging, it was proven to be a great educational experience that taught me about the approaches and practices that are used internally at Microsoft.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:cf5ded925e574af79c1fa14d01624d0b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</comments>
      <itunes:summary>Project ConclusionsDeveloping FallFury was a fun and educational activity. Besides the fact that I got to work with an amazing team of people who were willing to assist me with the testing and development, I learned some important points about the development process as a whole and have outlined them in this article.&amp;nbsp; Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-12-Project-Conclusion.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Go Outside Your Comfort ZoneThis past summer, I decided to tackle a new challenge—game development. Never before had I built a game from the ground up. Moreover, as I could already find my way around C# code, I decided that I wanted to make C&amp;#43;&amp;#43; the language of choice, and so worked with DirectX instead of XNA. Additionally, the project needed to be constructed with Windows 8 as the target platform and I’d have to rely on the WinRT stack. The concepts were new to me, but I figured that learning about a new platform and a new language would be more interesting than sticking to my comfort zone. Through FallFury I extended my knowledge about pointers, trigonometry, how DirectX handles a lot of the graphics legwork, and how to write HLSL shaders. It was a challenging but very rewarding experience. CommunicateThe most important part of any project is communication. There are always people who know more than you in one field or another, so don&#39;t hesitate to reach out to other developers and ask questions. Your code is not perfect, so talk about best practices used in production and how you can improve on what you already have—communication should not be limited to your team, floor, or even building. One bonus of my experience at Microsoft was discovering that a lot of developers, when not in a meeting or in the middle of an important assignment, are more than happy to help a fellow employee with a piece of advice or some code </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</link>
      <pubDate>Wed, 23 Jan 2013 23:57:48 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f8eb/37473ed7-1ccd-4afc-834d-d99ae5b2f8eb/FallFuryPart12_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-12-Conclusions/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 11 - Hardware Testing &amp; Debugging</title>
      <description><![CDATA[<h3>Hardware Testing &amp; Debugging</h3><p>As previously mentioned, FallFury runs on multiple types of hardware as long as that hardware supports Windows 8. This article describes the project’s general testing and debugging process, including setting the debug configurations and remote debugging.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing">http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Remote Debug</h4><p>When working on an application that targets different machines, it’s probably out of the question to install Visual Studio on each instance and move the solution from one source to another in order to run it and diagnose potential problems. Here is where <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30674">Remote Tools for Visual Studio 2012</a> come into play. Microsoft offers you three separate builds—tools for x86 systems, x64 systems, and ARM systems—also known as Surface RT.</p><p>Once the tools are running on the machine you want to debug, you have two choices. You can either install the remote debugger as a service, allowing it to constantly run in the background, or you can use the debugger on a per-launch basis. From a developer perspective, the choice doesn’t affect how your application is executed on the remote machine. From a security perspective, however, you need to be sure that you properly configure it so that no unwanted apps are remotely deployed.</p><p>Now you can start the Remote Debugger Configuration Wizard:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-8.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-9.jpg" alt="clip_image002" width="372" height="312" border="0"></a> <a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-6.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-7.jpg" alt="clip_image004" width="333" height="312" border="0"></a></p><p>This works on both the initial start-up and also any subsequent launch as a way to easily and quickly set the necessary remote debugger settings. Specifically, it is useful to configure the machine’s network settings, allowing cross-domain communications for debugging purposes.</p><p>Once the wizard is completed, launch the Remote Debugger Monitor. Notice that it lists your machine name and the port on which it’s running. This is necessary for configuring the project to send the package to a remote machine instead of the local one:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D-4.jpg"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb-5.jpg" alt="clip_image006" width="501" height="167" border="0"></a></p><p>The configuration depends on the network settings on both the local machine and the subnet as a whole. For example, in some cases, and especially on domain-joined machines, remote debugging is better done with the authentication disabled. Windows Authentication is used by default.</p><p>Since FallFury is a C&#43;&#43; project, the configuration for a remote session is different than, say, that of a C# Windows Store application. To configure the session, right click on the project in <strong>Solution Explorer</strong> and open the <strong>Debugging</strong> section. Make sure that Remote Machine is selected as the type of debugger to launch:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B3%5D-5.jpg"><img title="clip_image008" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008_thumb-6.jpg" alt="clip_image008" width="640" height="142" border="0"></a></p><p>Next, specify the machine name as well as whether the current session will require authentication:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B3%5D-3.jpg"><img title="clip_image010" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010_thumb-4.jpg" alt="clip_image010" width="640" height="196" border="0"></a></p><p>If you cannot specify the machine name, use the direct IPv4 address of that computer, minus the port <a>(unless you’ve explicitly set it to a port other than 4016, which is the assumed default).</a> Once the source machine connects to the remote one, you will see Visual Studio performing the deployment:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B3%5D-5.jpg"><img title="clip_image012" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012_thumb-5.jpg" alt="clip_image012" width="640" height="108" border="0"></a></p><h4>Configurations</h4><p>As a matter of convenience, it is always good to have different debug configurations that will define how your projects are built, especially if the project targets multiple platforms (such as ARM and x86). Visual Studio provides a <a href="http://msdn.microsoft.com/en-us/library/kwybya3w%28v=vs.80%29.aspx">Configuration Manager</a> that can be accessed from the debug target dropdown:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013%5B3%5D.png"><img title="clip_image013" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013_thumb.png" alt="clip_image013" width="300" height="199" border="0"></a></p><p>FallFury includes two separate projects—the game core, and the C#-based XML reader. Both need to be explicitly associated with separate target platforms in order to be correctly debugged. For that, profiles were created for both local and remote sessions:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B3%5D.png"><img title="clip_image014" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014_thumb.png" alt="clip_image014" width="640" height="186" border="0"></a></p><p>As with standard Debug/Release configurations, the ones shown above determine whether the project will carry debug symbols and support debugging commands. It is important to mention that as you switch configurations, you must be careful how you configure the graphic shaders. For each shader in the container folder, explicitly set the HLSL shader type and model. Otherwise the application deployment will fail:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016%5B3%5D-3.jpg"><img title="clip_image016" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016_thumb-4.jpg" alt="clip_image016" width="640" height="144" border="0"></a></p><h4>Remote Profiling</h4><p>Last but not least, when working with different hardware configurations it might be useful to perform application profiling or performance review. Fortunately, Visual Studio also provides this capability through the <a href="http://msdn.microsoft.com/en-us/library/hh977161.aspx"><strong>vsperf</strong></a> tool, which is already integrated in the IDE if you are using Visual Studio 2012 Professional or above.</p><p>To initiate a profiling session on a remote device, the Remote Debugger Monitor must be active. Make sure that the <strong>Remote Machine</strong> debug target is selected, and go to <strong>Analyze &gt; Start Performance Analysis</strong>:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image017%5B3%5D.png"><img title="clip_image017" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image017_thumb.png" alt="clip_image017" width="404" height="83" border="0"></a></p><p>On the remote machine, allow the <strong>vsperf</strong> process to run with administrative privileges. Once the profiling session completes and the data is analyzed, you can review the same performance indicators as you would when having a standard application run the profiler on the local machine:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image019%5B3%5D.jpg"><img title="clip_image019" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image019_thumb.jpg" alt="clip_image019" width="640" height="312" border="0"></a></p><h4>Conclusion</h4><p>Testing hardware outside the boundaries of a desktop machine is often a necessity, especially if the application relies on specific sensors, such as NFC, touch, or accelerometer. The remote debugging process is fairly streamlined and intuitive, with developing a proper network configuration allowing communication between machines requiring the most significant amount of effort. If you have problems getting the debugger to work, <a href="http://msdn.microsoft.com/en-us/library/bt727f1t.aspx">consult this article on MSDN</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:4e4e6ed2c2cc4a98946aa14d0161797b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</comments>
      <itunes:summary>Hardware Testing &amp;amp; DebuggingAs previously mentioned, FallFury runs on multiple types of hardware as long as that hardware supports Windows 8. This article describes the project’s general testing and debugging process, including setting the debug configurations and remote debugging. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-11-Hardware-Testing.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Remote DebugWhen working on an application that targets different machines, it’s probably out of the question to install Visual Studio on each instance and move the solution from one source to another in order to run it and diagnose potential problems. Here is where Remote Tools for Visual Studio 2012 come into play. Microsoft offers you three separate builds—tools for x86 systems, x64 systems, and ARM systems—also known as Surface RT. Once the tools are running on the machine you want to debug, you have two choices. You can either install the remote debugger as a service, allowing it to constantly run in the background, or you can use the debugger on a per-launch basis. From a developer perspective, the choice doesn’t affect how your application is executed on the remote machine. From a security perspective, however, you need to be sure that you properly configure it so that no unwanted apps are remotely deployed. Now you can start the Remote Debugger Configuration Wizard:   This works on both the initial start-up and also any subsequent launch as a way to easily and quickly set the necessary remote debugger settings. Specifically, it is useful to configure the machine’s network settings, allowing cross-domain communications for debugging purposes. Once the wizard is completed, launch the Remote Debugger Monitor. Notice that it lists your machine name and the port on which it’s running. This is necessary for configuring the project to send the package to a remote ma</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</link>
      <pubDate>Wed, 23 Jan 2013 23:57:44 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d2bf/2dea3e0d-559c-4efb-ae2d-a2c49c20d2bf/FallFuryPart11_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-11-Hardware-Testing--Debugging/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 10 - Charms</title>
      <description><![CDATA[<h3>Charms</h3><p>With the release of the Windows 8 operating system, applications are now able to easily integrate with each other and have a unified way to control their workflow through unique <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh464906.aspx">system-wide contracts</a> called <a href="http://blogs.msdn.com/b/going_metro/archive/2012/04/22/integrating-with-windows-8-charms-amp-contracts.aspx">Charms</a>. Out of the multitude of available options, FallFury leverages two charms—Share contract and Settings. This article describes how the integration is implemented.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-10-Charms">http://channel9.msdn.com/Series/FallFury/Part-10-Charms</a>&nbsp;.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-7.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-8.jpg" alt="clip_image002" width="640" height="362" border="0"></a></p><h4>The Share Contract</h4><p>When a user achieves a specific score in the game, he might decide to share it with his social circle. In Charms, that’s the purpose of the Share contract, which integrates directly with the OS.</p><p>Windows Store applications have the capability to expose their sharing capabilities and register as <a href="http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782">a share target</a>. For example, if there is a Twitter client out, it can register itself as an app through which content can be shared. FallFury, on the other hand, acts as a consumer that aggregates existing share targets and lets the user pick the one through which he wants to let the message out:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-5.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-6.jpg" alt="clip_image004" width="640" height="192" border="0"></a></p><p>Let’s take a look at how this process is built in the code-behind. The core is located in <strong>DirectXPage.xaml.cpp</strong>—the class responsible for XAML content manipulation in FallFury. First and foremost, you need to get the current instance of the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.datatransfer.datatransfermanager">DataTransferManager</a> class:</p><p><pre class="brush: cpp">
auto dataTransferManager = Windows::ApplicationModel::DataTransfer::DataTransferManager::GetForCurrentView();
</pre></p><p>Consider this a proxy that allows you to pass content between your app and other Windows Store apps that are executed in the context of the same sandbox. As the instance is obtained, hook it to the <strong>DataRequested</strong> event handler that will handle the scenario where the user invoked the sharing capability:</p><p><pre class="brush: cpp">
dataTransferManager-&gt;DataRequested &#43;= ref new 
    TypedEventHandler&lt;Windows::ApplicationModel::DataTransfer::DataTransferManager^,
    Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs^&gt;(this, &amp;DirectXPage::OnShareDataRequested);
</pre></p><p>&nbsp;</p><p>In the <strong>OnShareDataRequested</strong>, specify the information that goes into the sharing popup:</p><p><pre class="brush: cpp">
void DirectXPage::OnShareDataRequested(Windows::ApplicationModel::DataTransfer::DataTransferManager^ manager,Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs^ params)
{
    auto request = params-&gt;Request;
    request-&gt;Data-&gt;Properties-&gt;Title = &quot;Share Score&quot;;
    request-&gt;Data-&gt;Properties-&gt;Description = &quot;Tell your friends how much you scored in [DEN'S PROJECT]!&quot;;
    request-&gt;Data-&gt;SetText(&quot;I just scored &quot; &#43; StaticDataHelper::Score.ToString() &#43; &quot; in [DEN'S PROJECT]! Beat me! http://dennisdel.com&quot;);
}
</pre></p><p>&nbsp;</p><p>From that point, the control is in the user’s hand. The application cannot force the share, so unless you implement a direct API hook to a social service, the Share charm will only expose the endpoints available for sharing and will let you set the shareable content. You also don’t have to worry about the way the content will be shared—that will be handled by the target application:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D-3.jpg"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb-4.jpg" alt="clip_image006" width="571" height="411" border="0"></a></p><p>You can show the popup triggered by the Share charm from your application without having the user open the Charms Bar. To do this, call the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.datatransfer.datatransfermanager.showshareui">ShowShareUI</a> method:</p><p><pre class="brush: cpp">
void DirectXPage::ShareTopScore_Selected(MenuItem^ sender, Platform::String^ params)
{
    Windows::ApplicationModel::DataTransfer::DataTransferManager::ShowShareUI();
}
</pre></p><p>&nbsp;</p><p>This is exactly what the Share button does in the screenshot above. You should make this behavior predictable.</p><h4>The Settings Charm</h4><p>As you just saw, integrating basic sharing capabilities in FallFury is not too complicated. Working with settings is also a fairly easy task, though it involves some XAML work. While with sharing capabilities the work focused mostly on OS-based endpoints and application-specific popups, settings allow for full control over how they’re displayed.</p><p>For all Windows Store applications, settings should be handled via the Settings charm and not through dedicated application screens. Consider which settings that directly affect the user experience might be changed in FallFury:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B3%5D-4.jpg"><img title="clip_image008" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008_thumb-5.jpg" alt="clip_image008" width="506" height="230" border="0"></a></p><ul><li><strong>Music and SFX</strong> – the user can enable or disable music and sound effects, as well as control their volume. </li><li><strong>Accelerometer</strong> – depending on personal preferences, the user might decide to disable the accelerometer (it is enabled by default). The accelerometer can also be inverted—if the device is tilted to the right, the character will move to the left and vice-versa. Last but not least, even with dynamic screen rotation enabled on the device, the user can disable that rotation on the application level and lock the screen to one orientation, such as portrait or landscape. </li><li><strong>Character Movement</strong> – the character can be easily controlled via touch (swipe) or mouse. This behavior is enabled by default, but if the user decides to only use the mouse to direct shells, he can easily disable this feature here. </li></ul><p>As seen in the image above, the operating system provides the basic shell used to list the possible settings. Once one option is selected, however, further UI displays are delegated to the developer.</p><p>As with the share UI, the settings UI can be shown to the user from the application and not from the Charms Bar. Here is how to do this:</p><p><pre class="brush: cpp">
void DirectXPage::Settings_Selected(MenuItem^ sender, Platform::String^ params)
{
    SettingsPane::GetForCurrentView()-&gt;Show();
}
</pre></p><p>&nbsp;</p><p><a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.applicationsettings.settingspane">SettingsPane</a> is the core class that handles the settings display. It does not control how settings are stored or activated. When the main page loads, you need to make sure that you hook the current <strong>SettingsPane</strong> to a <strong>CommandRequested</strong> event handler. It will be triggered when the Settings capability is invoked:</p><p><pre class="brush: cpp">
SettingsPane::GetForCurrentView()-&gt;CommandsRequested &#43;= ref new TypedEventHandler&lt;SettingsPane^, SettingsPaneCommandsRequestedEventArgs^&gt;(this, &amp;DirectXPage::OnSettingsRequested);
</pre></p><p><strong>OnSettingsRequested</strong> is the function where the core setting selections are defined and hooked to their own event handlers:</p><p><pre class="brush: cpp">
void DirectXPage::OnSettingsRequested(Windows::UI::ApplicationSettings::SettingsPane^ settingsPane, Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs^ eventArgs)
{
    if (m_renderer-&gt;CurrentGameState == GameState::GS_PLAYING)
            StaticDataHelper::IsPaused = true;
    
    UICommandInvokedHandler^ handler = ref new UICommandInvokedHandler(this, &amp;DirectXPage::OnSettingsSelected);
    
        SettingsCommand^ generalCommand = ref new SettingsCommand(&quot;musicSfx&quot;, &quot;Music &amp; SFX&quot;, handler);
        eventArgs-&gt;Request-&gt;ApplicationCommands-&gt;Append(generalCommand);
    
    SettingsCommand^ accelerometerCommand = ref new SettingsCommand(&quot;accelerometer&quot;, &quot;Accelerometer&quot;, handler);
    eventArgs-&gt;Request-&gt;ApplicationCommands-&gt;Append(accelerometerCommand);
    
    SettingsCommand^ charMovementCommand = ref new SettingsCommand(&quot;charMovement&quot;, &quot;Character Movement&quot;, handler);
    eventArgs-&gt;Request-&gt;ApplicationCommands-&gt;Append(charMovementCommand);
}
</pre></p><p>Each <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.applicationsettings.settingscommand">SettingsCommand</a> is an item in the list displayed in the settings pane. When one is selected, <strong>OnSettingsSelected</strong> is called:</p><p><pre class="brush: cpp">
void DirectXPage::OnSettingsSelected(Windows::UI::Popups::IUICommand^ command)
{
    if (command-&gt;Id-&gt;ToString() == &quot;musicSfx&quot;)
    {
        stkMusicSfx-&gt;Width = 346.0f;
        grdSubMusicSfx-&gt;Height = m_renderer-&gt;m_renderTargetSize.Height;
        stkMusicSfx-&gt;IsOpen = true;
    }
    else if (command-&gt;Id-&gt;ToString() == &quot;accelerometer&quot;)
    {
        stkAccelerometerSettings-&gt;Width = 346.0f;
        grdAccelerometerSettings-&gt;Height = m_renderer-&gt;m_renderTargetSize.Height;
        stkAccelerometerSettings-&gt;IsOpen = true;
    }
    else if (command-&gt;Id-&gt;ToString() == &quot;charMovement&quot;)
    {
        stkCharacterMovement-&gt;Width = 346.0f;
        grdCharacterMovement-&gt;Height = m_renderer-&gt;m_renderTargetSize.Height;
        stkCharacterMovement-&gt;IsOpen = true;
    }

    WindowActivationToken = Window::Current-&gt;Activated &#43;= ref new WindowActivatedEventHandler(this, &amp;DirectXPage::OnWindowActivated);
}
</pre></p><p>Looking back at <strong>OnSettingsRequested</strong>, each command has a string identifier. When a command is invoked, that string identifier is returned through the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.popups.iuicommand">IUICommand</a> instance in the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.popups.iuicommand.id">Id</a> property. Based on that, I decided which popups to open. Since each has a similar structure, I am going to cover the implementation of just one—<strong>Music &amp; SFX</strong>.</p><p>Here is what the end result looks like:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B3%5D-2.jpg"><img title="clip_image010" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010_thumb-3.jpg" alt="clip_image010" width="640" height="461" border="0"></a></p><p>The panel on the left is a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.primitives.popup">Popup</a>, with two <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.primitives.togglebutton">ToggleButton</a> controls used to enable or disable generic music and sound effects. There are also two <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.slider">Slider</a> controls that are used to adjust the volume. The XAML for the above layout looks like this:</p><p><pre class="brush: xml">
&lt;Popup HorizontalAlignment=&quot;Right&quot; IsLightDismissEnabled=&quot;True&quot; x:Name=&quot;stkMusicSfx&quot; &gt;
    &lt;Grid Background=&quot;Black&quot; x:Name=&quot;grdSubMusicSfx&quot;  Width=&quot;346&quot;&gt;
        &lt;Grid.Transitions&gt;
            &lt;TransitionCollection&gt;
                &lt;RepositionThemeTransition /&gt;
            &lt;/TransitionCollection&gt;
        &lt;/Grid.Transitions&gt;

        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height=&quot;120&quot;&gt;&lt;/RowDefinition&gt;
            &lt;RowDefinition Height=&quot;*&quot;&gt;&lt;/RowDefinition&gt;
        &lt;/Grid.RowDefinitions&gt;

        &lt;StackPanel Grid.Row=&quot;0&quot; Orientation=&quot;Horizontal&quot; Margin=&quot;24,12,0,0&quot; &gt;
            &lt;Button Margin=&quot;0&quot; VerticalAlignment=&quot;Center&quot; x:Name=&quot;dismissAudioSettings&quot; Click=&quot;dismissAudioSettings_Click&quot; Style=&quot;{StaticResource BackButtonStyle}&quot;&gt;&lt;/Button&gt;
            &lt;TextBlock Margin=&quot;12,0,0,12&quot; Height=&quot;Auto&quot; VerticalAlignment=&quot;Center&quot; Text=&quot;Music &amp;amp; SFX&quot; Style=&quot;{StaticResource SubheaderTextStyle}&quot;&gt;&lt;/TextBlock&gt;
        &lt;/StackPanel&gt;

        &lt;StackPanel Grid.Row=&quot;1&quot; Margin=&quot;24,24,0,0&quot;&gt;
            &lt;StackPanel&gt;
                &lt;TextBlock Text=&quot;Music&quot; Style=&quot;{StaticResource BodyTextStyle}&quot;&gt;&lt;/TextBlock&gt;
                &lt;TextBlock  Width=&quot;346&quot; Text=&quot;This includes the theme track and level background music.&quot; Style=&quot;{StaticResource CaptionTextStyle}&quot; TextWrapping=&quot;Wrap&quot; Margin=&quot;0,12,12,12&quot; &gt;&lt;/TextBlock&gt;
                &lt;ToggleSwitch x:Name=&quot;tglMusic&quot; Toggled=&quot;tglMusic_Toggled&quot; IsOn=&quot;{Binding ElementName=XAMLPage,Path=MusicEnabled}&quot; Margin=&quot;-6,0,0,0&quot;&gt;&lt;/ToggleSwitch&gt;
            &lt;/StackPanel&gt;

            &lt;StackPanel Margin=&quot;0,24,0,0&quot;&gt;
                &lt;TextBlock Text=&quot;Music Volume&quot; Style=&quot;{StaticResource BodyTextStyle}&quot;&gt;&lt;/TextBlock&gt;
                &lt;Slider x:Name=&quot;sldMusicVolume&quot; ValueChanged=&quot;sldMusicVolume_ValueChanged&quot; Value=&quot;{Binding ElementName=XAMLPage,Path=MusicVolume, Mode=TwoWay}&quot; Minimum=&quot;0&quot; Maximum=&quot;100&quot; Margin=&quot;0,0,12,0&quot;&gt;&lt;/Slider&gt;
            &lt;/StackPanel&gt;

            &lt;StackPanel Margin=&quot;0,24,0,0&quot;&gt;
                &lt;TextBlock Text=&quot;Sound Effects&quot; Style=&quot;{StaticResource BodyTextStyle}&quot;&gt;&lt;/TextBlock&gt;
                &lt;TextBlock Width=&quot;346&quot; Text=&quot;Includes sounds played during the game (e.g. explosions).&quot; Style=&quot;{StaticResource CaptionTextStyle}&quot; TextWrapping=&quot;Wrap&quot; Margin=&quot;0,12,12,12&quot; &gt;&lt;/TextBlock&gt;
                &lt;ToggleSwitch x:Name=&quot;tglSFX&quot; Toggled=&quot;tglSFX_Toggled&quot; IsOn=&quot;{Binding ElementName=XAMLPage,Path=SFXEnabled}&quot; Margin=&quot;-6,0,0,0&quot;&gt;&lt;/ToggleSwitch&gt;
            &lt;/StackPanel&gt;

            &lt;StackPanel Margin=&quot;0,24,0,0&quot;&gt;
                &lt;TextBlock Text=&quot;SFX Volume&quot; Style=&quot;{StaticResource BodyTextStyle}&quot;&gt;&lt;/TextBlock&gt;
                &lt;Slider x:Name=&quot;sldSFXVolume&quot; ValueChanged=&quot;sldSFXVolume_ValueChanged&quot; Value=&quot;{Binding ElementName=XAMLPage,Path=SFXVolume, Mode=TwoWay}&quot; Minimum=&quot;0&quot; Maximum=&quot;100&quot; Margin=&quot;0,0,12,0&quot;&gt;&lt;/Slider&gt;
            &lt;/StackPanel&gt;

        &lt;/StackPanel&gt;

    &lt;/Grid&gt;
&lt;/Popup&gt;
</pre></p><p>For every Popup instance used for settings, make sure that <strong>IsLightDismissEnabled</strong> is set to true. This allows the user to dismiss the panel with a touch outside its boundaries, just like the stock system panels. Other than that, you are working with the standard XAML control set and can include virtually anything in your settings.</p><p>Notice, that the switches and sliders are bound to internal properties, such as <strong>SFXEnabled</strong> and <strong>MusicEnabled</strong>, that perform the binding <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh700353.aspx">via dependency property references</a>:</p><p><pre class="brush: cpp">
DependencyProperty^ DirectXPage::_musicEnabled = DependencyProperty::Register(&quot;MusicEnabled&quot;, 
bool::typeid, DirectXPage::typeid, nullptr);
DependencyProperty^ DirectXPage::_sfxEnabled = DependencyProperty::Register(&quot;SFXEnabled&quot;, 
bool::typeid, DirectXPage::typeid, nullptr);
</pre></p><p>&nbsp;</p><p>The properties themselves are declared in the <strong>DirectXPage</strong> header file:</p><p><pre class="brush: csharp">
static property DependencyProperty^ SFXVolumeProperty
{
    DependencyProperty^ get() { return _sfxVolume; }
}
property int SFXVolume
{
    int get() { return (int)GetValue(SFXVolumeProperty); }
    void set(int value) 
    { 
        SetValue(SFXVolumeProperty, value);
    }
}

static property DependencyProperty^ MusicVolumeProperty
{
    DependencyProperty^ get() { return _musicVolume; }
}
property int MusicVolume
{
    int get() { return (int)GetValue(MusicVolumeProperty); }
    void set(int value) 
    { 
        SetValue(MusicVolumeProperty, value);
    }
}
</pre></p><p>Let’s take a quick look at how settings are stored. I have a class called <strong>SettingsHelper</strong> that allows me to save, read, and check if specific settings exist. Here is the implementation:</p><p><pre class="brush: cpp">
#include &quot;pch.h&quot;
#include &quot;SettingsHelper.h&quot;

using namespace Windows::Storage;
using namespace Coding4Fun::FallFury::Helpers;

SettingsHelper::SettingsHelper(void)
{
}

void SettingsHelper::Save(Platform::String^ key, Platform::Object^ value)
{
    ApplicationDataContainer^ localSettings = ApplicationData::Current-&gt;LocalSettings;
    auto values = localSettings-&gt;Values;

    values-&gt;Insert(key, value);
}

Platform::Object^ SettingsHelper::Read(Platform::String^ key)
{
    ApplicationDataContainer^ localSettings = ApplicationData::Current-&gt;LocalSettings;
    auto values = localSettings-&gt;Values;

    return values-&gt;Lookup(key);
}

bool SettingsHelper::Exists(Platform::String^ key)
{
    ApplicationDataContainer^ localSettings = ApplicationData::Current-&gt;LocalSettings;
    auto values = localSettings-&gt;Values;

    return values-&gt;HasKey(key);
}
</pre></p><p>&nbsp;</p><p>It is clear that storage and retrieval heavily relies on the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdatacontainer.aspx">ApplicationDataContainer</a> class, the container class for local settings that eliminates the need for the developer to create his own setting files, instead delegating this task to the OS and utilizing a centralized storage for all Windows Store applications.</p><p>A typical scenario that utilizes the class above is executed when the toggle that manages the sound effects is switched:</p><p><pre class="brush: cpp">
void DirectXPage::tglSFX_Toggled(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    SettingsHelper::Save(&quot;sfxEnabled&quot;, tglSFX-&gt;IsOn);
    SFXEnabled = tglSFX-&gt;IsOn;
    AudioManager::IsSFXStarted = SFXEnabled;

    if (SFXEnabled)
    {
        AudioManager::AudioEngineInstance.StartSFX();
    }
    else
    {
        AudioManager::AudioEngineInstance.SuspendSFX();
    }
}
</pre></p><p>&nbsp;</p><p>The Boolean value above will be automatically serialized and stored. The files will be located at <strong>C:\Users\YOUR_USER_NAME\AppData\Local\Packages\PACKAGE_ID\Settings\settings.dat:</strong></p><p>&nbsp;</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B3%5D-4.jpg"><img title="clip_image012" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012_thumb-4.jpg" alt="clip_image012" width="640" height="192" border="0"></a></p><h4>Conclusion</h4><p>Implementing sharing through the OS channel in Windows 8 is extremely easy seeing as the developer does not necessarily have to worry about connecting the app to third-party API endpoints. Instead, the user controls the sharing, allowing flexibility of choice without requiring a major addition to the existing code base. It’s hard to predict which services might appear, and modifying the app to support each one of them would be next to impossible otherwise.</p><p>You can read more about settings in Windows Store applications <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh770544.aspx">here</a>.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:41450e373f904b80834ba14d01612a58">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms</comments>
      <itunes:summary>CharmsWith the release of the Windows 8 operating system, applications are now able to easily integrate with each other and have a unified way to control their workflow through unique system-wide contracts called Charms. Out of the multitude of available options, FallFury leverages two charms—Share contract and Settings. This article describes how the integration is implemented. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-10-Charms&amp;nbsp;.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles.  The Share ContractWhen a user achieves a specific score in the game, he might decide to share it with his social circle. In Charms, that’s the purpose of the Share contract, which integrates directly with the OS. Windows Store applications have the capability to expose their sharing capabilities and register as a share target. For example, if there is a Twitter client out, it can register itself as an app through which content can be shared. FallFury, on the other hand, acts as a consumer that aggregates existing share targets and lets the user pick the one through which he wants to let the message out:  Let’s take a look at how this process is built in the code-behind. The core is located in DirectXPage.xaml.cpp—the class responsible for XAML content manipulation in FallFury. First and foremost, you need to get the current instance of the DataTransferManager class: 
auto dataTransferManager = Windows::ApplicationModel::DataTransfer::DataTransferManager::GetForCurrentView();
 Consider this a proxy that allows you to pass content between your app and other Windows Store apps that are executed in the context of the same sandbox. As the instance is obtained, hook it to the DataRequested event handler that will handle the scenario where the user invoked the sharing capability: 
dataTransferManager-&amp;gt;DataRequested &amp;#43;= ref new 
    TypedEventHandler&amp;lt;Windows::ApplicationM</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms</link>
      <pubDate>Wed, 23 Jan 2013 23:57:40 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/d462/4039d0c3-2c48-4570-98d7-56de07f1d462/FallFuryPart10_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-10-Charms/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 9 - Particle System</title>
      <description><![CDATA[<h3>Particle System</h3><p>During gameplay there are scenarios during which users need to be visually notified that something has happened, such as a collision with an obstacle or an enemy shell. One way to do this is by having explosion or item breaking simulation, which brings us to the next large component in FallFury—the sprite-based particle system. It doesn’t offer as much power as a full-fledged particle system would, but it allows for effects that fit well within the overall theme and layout of the game.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System">http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System</a>&nbsp;.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>The Core</h4><p><strong>ParticleSystem</strong> is the dedicated folder in the project that contains everything needed to render multiple textures at once and displace them to create the desired effect:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001%5B3%5D.png"><img title="clip_image001" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001_thumb.png" alt="clip_image001" width="353" height="343" border="0"></a></p><p>A single particle carries information regarding its size, position, velocity, color shading, rotation, circular velocity, and scale. As with any other rendered entity, it has a bounding box that can be used to detect its intersection with other elements on the screen. In FallFury, this functionality is not used.</p><p>Its structure is as follows:</p><p><pre class="brush: cpp">
#pragma once
#include &quot;pch.h&quot;
struct Particle
{
    Particle(float2 size);
    Particle(float2 size, float4 shading);
    float2 Size;
    float2 Position;
    float2 Velocity;
    float4 Shading;
    float Rotation;
    float RotationVelocity;
    float Scale;
    bool IsWithinScreenBoundaries(float x, float y, Windows::Foundation::Rect screenBounds);
    Windows::Foundation::Rect GetBoundingBox();
};
</pre></p><p>The <strong>Particle</strong> class also happens to have two constructors—one that sets the particle to have the default shading, effectively removing the effect, and one where shading is dynamic. Note that a particle on its own doesn’t do much—it neither carries the associated texture nor has an internal loop that can be used in any given application part to display it.</p><p>The next core class is <strong>ParticleSet</strong>. It is used as a container for all the particles associated with a specific effect. For example, if I want to create flying stuffing when the bear hits an obstacle, I create a new ParticleSet instance and define the necessary particle properties:</p><ul><li><strong>Lifespan</strong> – a particle set does not constantly animate. It displays the particles for a limited amount of time, and displaces them by the given velocity values, and then self-destructs. </li><li><strong>Texture</strong> – all particles in a <strong>ParticleSet</strong> have the same texture. Going back to the stuffing example, there is a single PNG file used to render multiple variable-sized particles on collision. </li><li><strong>IsAlive </strong>– this is the flag that shows whether the particle set should be rendered in the first place. If it is set to <strong>false</strong> then, regardless of the conditions, this <strong>ParticleSet</strong> instance is ignored. </li><li><strong>ShouldScale </strong>– this flag determines whether particles will automatically increase their scale as they are being displaced, creating the effect of a particle approaching the screen. This effect is applied to each particle in the set. </li></ul><p>The container class is used to update the particles through the Update function:</p><p><pre class="brush: cpp">
void ParticleSet::Update(float timeDelta)
{
    float quat = _lifespan / 0.016f;
    float decrement = 1.0f / quat;
    
    if (_totalTime &lt;= _lifespan &amp;&amp; _isAlive)
    {
        _totalTime &#43;= timeDelta;
        
        for (auto particle = _particles.begin(); particle != _particles.end(); particle&#43;&#43;)
        {
            if (_shouldScale)
                particle-&gt;Scale &#43;= 0.2f;
            
            particle-&gt;Shading.a -= decrement;
            particle-&gt;Position = float2(particle-&gt;Position.x &#43; particle-&gt;Velocity.x,
                            particle-&gt;Position.y &#43; particle-&gt;Velocity.y);
            
            if (!_shouldScale)
                particle-&gt;Rotation &#43;= particle-&gt;RotationVelocity;
        }
    }
    else
    {
        _totalTime = 0.0f;
        _isAlive = false;
    }
}
</pre></p><p>As it relies on the <strong>_isAlive</strong> flag, the <strong>Update</strong> loop is only used when the particle displacement is activated via the <strong>Activate</strong> function:</p><p><pre class="brush: cpp">
void ParticleSet::Activate(float2 position, float2 velocity, bool randomize, bool scale)
{
    for (auto particle = _particles.begin(); particle != _particles.end(); particle&#43;&#43;)
    {
        particle-&gt;Position = position;

        if (randomize)
            particle-&gt;Velocity = float2(RandFloat(-5.0f,5.0f), RandFloat(-5.0f, 5.0f));
        else
            particle-&gt;Velocity = float2(velocity.x &#43; RandFloat(-0.6f, 0.6f), velocity.y &#43; RandFloat(-0.6f, 0.6f));;
    }

    _shouldScale = scale;
    _isAlive = true;
}
</pre></p><p>When a set is activated, several user-defined parameters come into play. The position is set no matter what and is used to create the source point from which the particles start appearing. The velocity, on the other hand, can be randomized between the values of <em>-5</em> and <em>5</em> pixels per update loop, on both the X-axis and the Y-axis. If randomized, large amount of particles will create an explosion that starts from the center point and expands towards all quadrants. When the velocity is not randomized, it creates a triangular expansion grid on which particles deviate from the center point in one of the given directions:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image003%5B3%5D-1.png"><img title="clip_image003" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image003_thumb-1.png" alt="clip_image003" width="640" height="235" border="0"></a></p><p>When it’s time to render the particles, the sprite batch associated with the current game screen is used to pass a texture for each particle registered in the set:</p><p><pre class="brush: cpp">
void ParticleSet::Render(SpriteBatch ^spriteBatch)
{
    for (auto particle = _particles.begin(); particle != _particles.end(); particle&#43;&#43;)
        {
        if (GamePlayScreen::Manager-&gt;IsWithinScreenBoundaries(particle-&gt;Position))
                    spriteBatch-&gt;Draw(_texture.Get(), particle-&gt;Position, PositionUnits::DIPs,
                    particle-&gt;Size * particle-&gt;Scale, SizeUnits::Pixels, particle-&gt;Shading, particle-&gt;Rotation);
        }
}
</pre></p><p>Although there is no flag check inside the Render method that would make sure that the set is alive, this can be done outside of it by calling <strong>IsAlive</strong>, which will return the flag value:</p><p><pre class="brush: cpp">
bool ParticleSet::IsAlive()
{
    return _isAlive;
}
</pre></p><p>&nbsp;</p><p>Let’s now take a look at the class that managed the particle flow—<strong>ParticleCore</strong>.</p><h4>The Particle Manager</h4><p><strong>ParticleCore</strong> is the class that manages internal particle sets, and is also the proxy for set activation, update, and rendering. Here is its structure:</p><p><pre class="brush: cpp">
#pragma once
#include &quot;pch.h&quot;
#include &quot;ParticleSet.h&quot;
#include &lt;list&gt;
#include &lt;map&gt;

class ParticleCore
{
    public:
    ParticleCore();
    ParticleCore(Coding4Fun::FallFury::Screens::GameScreenBase^);
    virtual ~ParticleCore();
    
    void CreatePreCachedParticleSets();
    void ActivateSet(Platform::String^, float2);
    void ActivateSet(Platform::String^, float2, float2);
    void ActivateSet(Platform::String^, float2, bool);
    void ActivateSet(Platform::String^, float2, float2, bool);
    void ActivateSet(Platform::String^, float2, float2, bool, bool scale);
    void Update(float);
    void Render();
    
    private:
        std::list&lt;ParticleSet&gt;                                                    _renderParticleSets;
        std::map&lt;Platform::String^, ParticleSet*&gt;                                _particleSetCache;
        std::map&lt;Platform::String^, Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;&gt;    _textureCache;
        Coding4Fun::FallFury::Screens::GameScreenBase^                            _screenBase;
};
</pre></p><p>As previously mentioned, set activation can be done with some omitted parameters inferred by the system, such as randomization of velocity or particle scaling, which is the reason why you see multiple overloads for <strong>ActivateSet</strong>.</p><p><strong>ParticleCore</strong> is also the container for pre-defined sets that have specific textures and properties that are dumped in the particle set cache (internal <strong>_particleSetCache</strong>). The cache is reusable and even though sets can be activated and destroyed, the cache remains intact for the duration of the game unless explicitly reset or modified. The texture cache is an addition to the particle set cache and is used as a helper container to temporarily store the textures used for individual particles.</p><p>Taking a look under the hood at the <strong>CreatePreCachedParticleSets</strong> function, you can see multiple sets that can be used in the game, each with different properties. Here is a snippet that shows how the bear stuffing explosion set is created:</p><p><pre class="brush: cpp">
auto smallExplosionSet = new ParticleSet(_textureCache[&quot;Stuffing&quot;], LIFESPAN);
for (int i = 0; i &lt; 20; i&#43;&#43;)
{
    float size = RandFloat(50.0f, 100.0f);
    Particle particle(float2(size, size));
    smallExplosionSet-&gt;AddParticle(particle);
}
</pre></p><p>&nbsp;</p><p>Once all the particles are in place for that specific set, it is added to the global particle set cache:</p><p><pre class="brush: cpp">
_particleSetCache[&quot;SmallExplosion&quot;] = smallExplosionSet;
</pre></p><p>The particle set cache is not explicitly used to render anything on the screen. Rather, that task is delegated to the rendering cache. When a set is activated, the cache is inspected for the given key, its Activate function is called, marking it as alive, and the set itself is pushed on the rendering stack:</p><p><pre class="brush: cpp">
void ParticleCore::ActivateSet(Platform::String^ name, float2 position, float2 velocity, bool randomize, bool scale)
{
    ParticleSet set = ParticleSet(*_particleSetCache[name]);
    set.Activate(position, velocity, randomize, scale);
    _renderParticleSets.push_back(set);
}
</pre></p><p>&nbsp;</p><p>The Render loop takes care of invoking the proper <strong>SpriteBatch</strong> drawing functions for each set that is in that stack:</p><p><pre class="brush: cpp">
void ParticleCore::Render()
{
    for (auto set = _renderParticleSets.begin(); set != _renderParticleSets.end(); &#43;&#43;set)
    {
        if ((*set).IsAlive())
        {
            (*set).Render(_screenBase-&gt;CurrentSpriteBatch);
        }
    }
}
</pre></p><p>&nbsp;</p><p>Notice that, as previously mentioned, the set does not perform the life check on itself when rendering. Instead, the manager class performs this action. The same applies to the <strong>Update</strong> loop:</p><p><pre class="brush: cpp">
void ParticleCore::Update(float timeDelta)
{
    for (auto set = _renderParticleSets.begin(); set != _renderParticleSets.end();)
    {
        if ((*set).IsAlive())
        {
            (*set).Update(timeDelta);
            &#43;&#43;set;
        }
        else
        {
            set = _renderParticleSets.erase(set);
        }
    }
}
</pre></p><p>&nbsp;</p><p>The textures for each set are individually loaded in the <strong>CreatePreCachedParticleSets</strong>. Each instance is internally pushed into the cache and also added to the sprite batch associated with the current game screen, where <strong>ParticleCore</strong> is used:</p><p><pre class="brush: cpp">
Loader-&gt;LoadTexture(&quot;DDS\\stuffing.dds&quot;, &amp;_textureCache[&quot;Stuffing&quot;], nullptr);
_screenBase-&gt;CurrentSpriteBatch-&gt;AddTexture(_textureCache[&quot;Stuffing&quot;].Get());
</pre></p><p>&nbsp;</p><p>Once everything is loaded, the <strong>ParticleCore</strong> is ready to go and you can use as many particles as necessary in any part of the application. In <strong>GamePlayScreen</strong>, particle sets are activated in many cases. For example, if the bear dies:</p><p><pre class="brush: cpp">
void GamePlayScreen::CheckBearHealth()
{
    if (GameBear-&gt;CurrentHealth &lt;= 0)
    {
        m_particleSystem.ActivateSet(&quot;Buttons&quot;,GameBear-&gt;Position, true);
        GameBear-&gt;Kill();
        StopBackground();
    }
}
</pre></p><p>&nbsp;</p><h4>Conclusion</h4><p>Implementing a sprite-based particle system is not complicated, but it requires depending on a number of assumptions. For example, when a particle set is created, you might consider the fact that some hardware can handle drawing only a given number of sprites at the same time. If a particle set is rendered on a desktop machine, there is no guarantee that the same set will successfully render on an ARM device. Therefore, plan accordingly. For each particle set, create a lifespan that fits the scenario without wasting resources on rendering unnecessary particles. As an additional failsafe, you might want to disable specific particle set types when a Direct3D feature level below 10.0 is detected.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d7f02957c420452a8791a14d01580aad">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System</comments>
      <itunes:summary>Particle SystemDuring gameplay there are scenarios during which users need to be visually notified that something has happened, such as a collision with an obstacle or an enemy shell. One way to do this is by having explosion or item breaking simulation, which brings us to the next large component in FallFury—the sprite-based particle system. It doesn’t offer as much power as a full-fledged particle system would, but it allows for effects that fit well within the overall theme and layout of the game. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-9-Particle-System&amp;nbsp;.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. The CoreParticleSystem is the dedicated folder in the project that contains everything needed to render multiple textures at once and displace them to create the desired effect:  A single particle carries information regarding its size, position, velocity, color shading, rotation, circular velocity, and scale. As with any other rendered entity, it has a bounding box that can be used to detect its intersection with other elements on the screen. In FallFury, this functionality is not used. Its structure is as follows: 
#pragma once
#include &amp;quot;pch.h&amp;quot;
struct Particle
{
    Particle(float2 size);
    Particle(float2 size, float4 shading);
    float2 Size;
    float2 Position;
    float2 Velocity;
    float4 Shading;
    float Rotation;
    float RotationVelocity;
    float Scale;
    bool IsWithinScreenBoundaries(float x, float y, Windows::Foundation::Rect screenBounds);
    Windows::Foundation::Rect GetBoundingBox();
};
 The Particle class also happens to have two constructors—one that sets the particle to have the default shading, effectively removing the effect, and one where shading is dynamic. Note that a particle on its own doesn’t do much—it neither carries the associated texture nor has an internal loop that can be used</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System</link>
      <pubDate>Wed, 23 Jan 2013 23:57:36 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/af7e/b408253b-7538-45b2-9b34-0685e059af7e/FallFuryPart9_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-9-Particle-System/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 8 - Element Interaction</title>
      <description><![CDATA[<h3>Element Interaction</h3><p>During the gameplay multiple entities interact with each other to make the gaming experience what it is. The bear collides with obstacles and collects buttons, monsters shoot shells that can fly off-screen or hit the bear—all this is possible with the help of the basic collision detection techniques that are implemented in FallFury.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction">http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction</a>&nbsp;. For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Buttons</h4><p>Buttons are bonus-boosters that can be placed by the level designer anywhere on the screen in game mode. These are relatively small entities, which are displaced vertically with each cycle of the <strong>Update</strong> loop and move in the opposite direction, but with the same velocity, as the main character.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B2%5D-8.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb-9.png" alt="image" width="624" height="351" border="0"></a></p><p>Looking at the Update function in the GamePlayScreen class, you will notice this call:</p><p><pre class="brush: cpp">
UpdateButtons();
</pre></p><p><strong>UpdateButtons</strong> can be considered the button manager function responsible for removing the collected buttons from the rendering stack, counting them, and checking for a button collision when the bear is in close proximity. The implementation looks like this:</p><p><pre class="brush: cpp">
void GamePlayScreen::UpdateButtons()
{
    Windows::Foundation::Rect livingEntityBoundingBox = GameBear-&gt;GetBoundingBox();
    for (auto button = m_buttons.begin(); button != m_buttons.end();)
    {
        (*button)-&gt;Position.x = (*button)-&gt;PixelDiff &#43; LoBoundX;
        (*button)-&gt;Position.y -= GameBear-&gt;Velocity.y;
        if (Geometry::IsInProximity(GameBear-&gt;Position,(*button)-&gt;Position, 100))
        {
            Windows::Foundation::Rect obstacleRect = (*button)-&gt;GetBoundingBox();
            if (livingEntityBoundingBox.IntersectsWith(obstacleRect))
            {
                AudioManager::AudioEngineInstance.StopSoundEffect(Coin);
                AudioManager::AudioEngineInstance.PlaySoundEffect(Coin);
                m_particleSystem.ActivateSet(&quot;Sparkle&quot;, (*button)-&gt;Position,float2(RandFloat(-6.0f,6.0f),RandFloat(-10.0f, -5.0f)));
                StaticDataHelper::ButtonsCollected&#43;&#43;;
                button = m_buttons.erase(button);
            }
            else
            &#43;&#43;button;
        }
        else
        {
            &#43;&#43;button;
        }
    }
}
</pre></p><p>For performance reasons, FallFury supports composite bounding box creation as well as simple box creation. As mentioned earlier in the series, the main character is not composed of a single texture, but rather multiple sprites that are cross-positioned to create a single visual entity. To give you a better idea of what composite vs. simple boxing looks like, take a look at the images below:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-10.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B1%5D-7.png" alt="image" width="266" height="225" border="0"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B8%5D-4.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B2%5D-8.png" alt="image" width="226" height="222" border="0"></a></p><p>The image on the left shows how each part of the bear has its own bounding box, and each will be used for collision checking. In the image on the right, the bear has a single bounding box, creating minor potential gaps, but gaining performance.</p><p>Going back to <strong>UpdateButtons</strong>, once the bounding box is obtained, I iterate through the button collection and make sure that each item is located in the proper space:</p><p><pre class="brush: cpp">
(*button)-&gt;Position.x = (*button)-&gt;PixelDiff &#43; LoBoundX;
(*button)-&gt;Position.y -= GameBear-&gt;Velocity.y;
</pre></p><p>&nbsp;</p><p>The constant position checks are necessary because FallFury supports dynamic orientation changes. When the user switches from portrait to landscape mode and vice-versa, rendered elements on the screen are not automatically repositioned. Setting the X position is easy as long as there is a fixed button margin (from the left side of the screen: <strong>LoBoundX</strong>) and adding it to the current <strong>LoBoundX</strong> value results in a proper X location. There is no need to do the same check on the Y-axis because the level length remains the same regardless of the current screen orientation. The adjustment made relative the Y position is bound to the bear velocity. If the bear moves slower, buttons will also scroll slower.</p><p>Given that all buttons are properly positioned, a proximity check is performed on each button passed through the loop. If the bear position is at least 100 pixels away from the current button, the corresponding bounding box is obtained and an intersect check is performed. In simple boxing mode, this is done via <strong>Windows::Foundation::Rect::IntersectsWith</strong>:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B11%5D-4.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B3%5D-9.png" alt="image" width="562" height="61" border="0"></a></p><p>If a collision occurs, the appropriate sound effect is played and a particle set is activated to create a visual notification of the action. After the button counter is incremented, the button is removed from the local collection, effectively being removed from the rendering stack.</p><h4>Power-ups</h4><p>As the bear flies towards the end of the level, it might encounter bonuses to improve its ability to fight incoming enemies or protect from damage caused by enemy ammo or obstacles. The process behind displaying power-ups on the screen and determining whether there was a collision with the main character is similar to <strong>UpdateButtons</strong>.</p><p>The core function for this task is <strong>UpdatePowerups</strong>:</p><p><pre class="brush: cpp">
void GamePlayScreen::UpdatePowerups(float timeDelta)
{
    if (m_powerups.size() &gt; 0)
    {
        for (auto powerup = m_powerups.begin(); powerup != m_powerups.end(); powerup&#43;&#43;)
        {
            (*powerup)-&gt;Update(timeDelta);
            (*powerup)-&gt;Position.x = (*powerup)-&gt;PixelDiff &#43; LoBoundX;
            (*powerup)-&gt;Position.y -= GameBear-&gt;Velocity.y;
        }
    }
    CheckForCollisionWithPowerups();
}
</pre></p><p>&nbsp;</p><p>One difference you probably noticed in the snippet above is the fact that the collision check is now done through a separate function—<strong>CheckForCollisionWithPowerups</strong>:</p><p><pre class="brush: cpp">
void GamePlayScreen::CheckForCollisionWithPowerups()
{
    Powerup^ currentPowerup;
    Windows::Foundation::Rect livingEntityBoundingBox = GameBear-&gt;GetBoundingBox();
    for (auto powerup = m_powerups.begin(); powerup != m_powerups.end();)
    {
        currentPowerup = (*powerup);
        if (Geometry::IsInProximity(GameBear-&gt;Position,currentPowerup-&gt;Position, 100))
        {
            Windows::Foundation::Rect obstacleRect = currentPowerup-&gt;GetBoundingBox();
            if (livingEntityBoundingBox.IntersectsWith(obstacleRect))
            {
                AudioManager::AudioEngineInstance.PlaySoundEffect(GenericPowerup);
                GameBear-&gt;PickupPowerup(currentPowerup, &amp;m_particleSystem);
                powerup = m_powerups.erase(powerup);
            }
            else
            &#43;&#43;powerup;
        }
        else
        {
            &#43;&#43;powerup;
        }
    }
}
</pre></p><p>If an intersection is detected between the boxed bear and the power-up texture, the current power-up is passed to the <strong>Bear</strong> instance and the appropriate type of action is selected:</p><p><pre class="brush: cpp">
void Bear::PickupPowerup(Powerup^ powerup, ParticleCore* ParticleSystem)
{
    switch (powerup-&gt;Type)
    {
        case PowerupType::PARACHUTE:
        {
            m_previousVelocity = Velocity.y;
            SetParachute(powerup-&gt;Lifespan);
            Velocity.y -= powerup-&gt;Effect;
            ParticleSystem-&gt;ActivateSet(&quot;ScalableParachute&quot;, Position, 0.0f, false, true);
            break;
        }
        case PowerupType::HEALTH:
        {
            CurrentHealth = MaxHealth;
            ParticleSystem-&gt;ActivateSet(&quot;ScalableHeart&quot;, Position, 0.0f, false, true);
            break;
        }
        case PowerupType::BUBBLE:
        {
            if (IsHelmetEnabled)
            {
                IsHelmetEnabled = false;
                DamageDivider = 1.0f;
            }
            else
            {
                DamageDivider = powerup-&gt;Effect;
            }
            IsBubbleEnabled = true;
            m_maxBubbleCounter = powerup-&gt;Lifespan;
            ParticleSystem-&gt;ActivateSet(&quot;ScalableBubble&quot;, Position, 0.0f, false, true);
            break;
        }
        // [...]
        case PowerupType::BOOMERANG:
        {
            m_weaponType = powerup-&gt;Type;
            m_weaponTexture = m_boomerangTexture;
            CurrentDamage = powerup-&gt;Effect;
            m_weaponSize = float2(225.0f, 205.0f) * 0.5f;
            ParticleSystem-&gt;ActivateSet(&quot;ScalableBoomerang&quot;, Position, 0.0f, false, true);
            break;
        }
    }
}
</pre></p><p>Depending on the power-up, textures are added to the bear model and later passed to the rendering stack (if the power-up type is <strong>PARACHUTE</strong>), some textures and capabilities are replaced (<strong>BOOMERANG</strong>), or the bear capabilities are temporarily modified (<strong>BUBBLE</strong>):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B14%5D-4.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B4%5D-3.png" alt="image" width="359" height="358" border="0"></a></p><p>If one of the temporary power-ups is enabled n the <strong>Update</strong> loop, dedicated timers ensure that ability enhancement does not last longer than necessary. As an example, here is the snippet that controls the bubble:</p><p><pre class="brush: cpp">
if (IsBubbleEnabled)
{
    m_currentBubbleCounter &#43;= timeDelta;
    if (m_currentBubbleCounter &gt; m_maxBubbleCounter)
    {
        IsBubbleEnabled = false;
        DamageDivider = 1.0f;
        m_currentBubbleCounter = 0.0f;
    }
}
</pre></p><p>&nbsp;</p><h4>Ammo Collisions</h4><p>There are also objects that direct ammo at either the enemy or the bear. After release, each shell follows a linear path towards the target, and while the user directs the shells that originate from the bear, those released by enemy entities automatically target the bear. In this case, the ammo needs to collide with an object to either damage or kill it. When a shell is released, it is added to the general ammo collection that is later updated internally:</p><p><pre class="brush: cpp">
void GamePlayScreen::UpdateAmmo(float timeDelta)
{
    for (auto shell = m_ammoCollection.begin(); shell != m_ammoCollection.end(); shell&#43;&#43;)
    {
        (*shell)-&gt;Update(timeDelta, &amp;m_particleSystem);
    }
}
</pre></p><p>&nbsp;</p><p>At this point, the rendering system does not differentiate between friendly and enemy ammo—all it knows is that each item in the collection must have a new position when a new frame is rendered. The <strong>CheckForCollisionsWithAmmo</strong> function checks for ammo collisions:</p><p><pre class="brush: cpp">
void GamePlayScreen::CheckForCollisionWithAmmo(LivingEntity^ entity)
{
    if (entity != nullptr)
    {
        Windows::Foundation::Rect livingEntityBoundingBox = entity-&gt;GetBoundingBox();
        if (entity-&gt;IsFriendly)
        {
            for (auto ammo = m_ammoCollection.begin(); ammo != m_ammoCollection.end();)
            {
                if (!(*ammo)-&gt;IsFriendly)
                {
                    Windows::Foundation::Rect ammoBoundingBox = (*ammo)-&gt;GetBoundingBox();
                    if (livingEntityBoundingBox.IntersectsWith(ammoBoundingBox))
                    {
                        m_particleSystem.ActivateSet(&quot;SmallExplosion&quot;,entity-&gt;Position, true);
                        entity-&gt;InflictDamage((*ammo)-&gt;HealthDamage);
                        GameBear-&gt;RedShade();
                        AudioManager::AudioEngineInstance.PlaySoundEffect(OuchA);
                        AudioManager::AudioEngineInstance.PlaySoundEffect(HardSoftCollision);
                        CheckBearHealth();
                        ammo = m_ammoCollection.erase(ammo);
                    }
                    else
                    {
                        &#43;&#43;ammo;
                    }
                }
                else
                {
                    &#43;&#43;ammo;
                }
            }
        }
        else
        {
            for (auto ammo = m_ammoCollection.begin(); ammo != m_ammoCollection.end();)
            {
                if ((*ammo)-&gt;IsFriendly)
                {
                    Windows::Foundation::Rect ammoBoundingBox = (*ammo)-&gt;GetBoundingBox();
                    if (livingEntityBoundingBox.IntersectsWith(ammoBoundingBox))
                    { 
                        Monster^ monster = ((Monster^)entity);
                        if (!monster-&gt;IsDead &amp;&amp; monster-&gt;IsActive)
                        {
                            m_particleSystem.ActivateSet(&quot;SmallExplosion&quot;, entity-&gt;Position, true);
                            entity-&gt;InflictDamage((*ammo)-&gt;HealthDamage);
                            monster-&gt;RedShade();
                            monster-&gt;CheckIfAlive();
                            AudioManager::AudioEngineInstance.PlaySoundEffect(SharpSoftCollision);
                        }
                        ammo = m_ammoCollection.erase(ammo);
                    }
                    else
                    {
                        &#43;&#43;ammo;
                    }
                }
                else
                {
                    &#43;&#43;ammo;
                }
            }
        }
    }
}
</pre></p><p>When the function is called, it is usually run against an entity that is present on the screen, such as the main character. Regardless of whether the enemy or the friendly character fired the shot, the shot cannot inflict damage to its source, and that’s why the function implements the ammo-to-entity crosscheck. If the ammo collides with any shells intersecting the entity bounding box, a collision is counted and health verification is performed to ensure that the character is still alive and that the game should continue. The bear’s health is checked via <strong>CheckBarHealth</strong>:</p><p><pre class="brush: cpp">
void GamePlayScreen::CheckBearHealth()
{
    if (GameBear-&gt;CurrentHealth &lt;= 0)
    {
        m_particleSystem.ActivateSet(&quot;Buttons&quot;,GameBear-&gt;Position, true);
        GameBear-&gt;Kill();
        StopBackground();
    }
}
</pre></p><p>That said, not all ammo will collide with entities on the screen. Some of it will go out-of-bounds, and without an explicit cleanup process in place out-of-bounds ammo is constantly re-rendered even though the end user has no way of seeing it. To avoid this, there is a helper function—<strong>CheckForOutOfBoundsAmmo</strong>:</p><p><pre class="brush: cpp">
void GamePlayScreen::CheckForOutOfBoundsAmmo()
{
    for (auto l_Iter = m_ammoCollection.begin(); l_Iter != m_ammoCollection.end(); /* nothing here */ )
    {
        if (!GamePlayScreen::Manager-&gt;IsWithinScreenBoundaries((*l_Iter)-&gt;Position))
        {
            l_Iter = m_ammoCollection.erase(l_Iter);
        }
        else
        {
            &#43;&#43;l_Iter;
        }
    }
}
</pre></p><p>If any shell flies outside the screen bounding box, its instance is erased from the collection and the renderer no longer worries about allocating memory for an irrelevant item. To give you an idea of how that happens, here is a snippet that shows how the <strong>RenderScreen</strong> function handles the current ammo set:</p><p><pre class="brush: cpp">
if (!m_ammoCollection.empty())
{
    for (auto shell = m_ammoCollection.begin(); shell != m_ammoCollection.end(); shell&#43;&#43;)
    {
        if (!(*shell)-&gt;IsFriendly)
        {
            (*shell)-&gt;Render();
        }
        else
        {
            GameBear-&gt;RenderShell((*shell)-&gt;Position, (*shell)-&gt;Rotation);
        }
    }
}
</pre></p><p>&nbsp;</p><h4>Conclusion</h4><p>Element interaction is a core part of the FallFury experience. Separate handlers are implemented for each of them to ensure maximum flexibility when it comes to adding or removing components without breaking major parts of the code-base. Handling is mainly accomplished in the Update loop by iterating through registered entity sets, such as ammo, and verifying whether an action should be taken. Be cautious when implementing this kind of scenario with large entities and data sets—having multiple loops running simultaneously might tax machine performance, especially on low-power configurations such as ARM.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:79ffea1b09074fc7bfd9a14d01549989">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction</comments>
      <itunes:summary>Element InteractionDuring the gameplay multiple entities interact with each other to make the gaming experience what it is. The bear collides with obstacles and collects buttons, monsters shoot shells that can fly off-screen or hit the bear—all this is possible with the help of the basic collision detection techniques that are implemented in FallFury. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-8-Element-Interaction&amp;nbsp;. For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. ButtonsButtons are bonus-boosters that can be placed by the level designer anywhere on the screen in game mode. These are relatively small entities, which are displaced vertically with each cycle of the Update loop and move in the opposite direction, but with the same velocity, as the main character.  Looking at the Update function in the GamePlayScreen class, you will notice this call: 
UpdateButtons();
 UpdateButtons can be considered the button manager function responsible for removing the collected buttons from the rendering stack, counting them, and checking for a button collision when the bear is in close proximity. The implementation looks like this: 
void GamePlayScreen::UpdateButtons()
{
    Windows::Foundation::Rect livingEntityBoundingBox = GameBear-&amp;gt;GetBoundingBox();
    for (auto button = m_buttons.begin(); button != m_buttons.end();)
    {
        (*button)-&amp;gt;Position.x = (*button)-&amp;gt;PixelDiff &amp;#43; LoBoundX;
        (*button)-&amp;gt;Position.y -= GameBear-&amp;gt;Velocity.y;
        if (Geometry::IsInProximity(GameBear-&amp;gt;Position,(*button)-&amp;gt;Position, 100))
        {
            Windows::Foundation::Rect obstacleRect = (*button)-&amp;gt;GetBoundingBox();
            if (livingEntityBoundingBox.IntersectsWith(obstacleRect))
            {
                AudioManager::AudioEngineInstance.StopSoundEffect(Coin);
                AudioManager::AudioEngineInstance.PlaySoundEf</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction</link>
      <pubDate>Wed, 23 Jan 2013 23:57:25 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/3d85/e97b9237-10bd-414e-b825-986d050e3d85/FallFuryPart8_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-8-Element-Interaction/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 7 - Animations</title>
      <description><![CDATA[<h3>Animations &amp; Item Transitions</h3><p>FallFury relies on a lot of dynamic content. As you already aware of how <strong>SpriteBatch</strong> is invoked inside the FallFury rendering stack, this article focuses on how dynamic activities are handled on existing textures and entities. If you need a quick look at what was already covered, refer to Part 3 of the series.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-7-Animations">http://channel9.msdn.com/Series/FallFury/Part-7-Animations</a>&nbsp;. For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h3>Menu Screen</h3><p>The first animated element shown in the menu screen is the bear, which is positioned in the top half of the viewport. Notice that the bear moves its paws as well as moving across the screen:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B2%5D-7.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb-8.png" alt="image" width="624" height="351" border="0"></a></p><p>The bear is implemented in the <strong>GameBear</strong> class and is the normal playable entity that is invincible when animated outside the scope of the gameplay screen. Its full body image is composed of four textures:</p><p><pre class="brush: cpp">
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;        m_head;
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;        m_leftPaw;
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;        m_rightPaw;

Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;        m_body // Exposed through LivingEntity;
</pre></p><p>Each of these textures is internally dependent on the coupled float rotation and position values passed to the sprite batch in the host container (the parent screen):</p><p><pre class="brush: cpp">
HostContainer-&gt;CurrentSpriteBatch-&gt;Draw(
    m_rightPaw.Get(),
    m_rightPawPosition,
    PositionUnits::DIPs,
    float2(522.0f, 141.0f) * Scale,
    SizeUnits::Pixels,
    m_shading,
    m_rightPawRotation - 0.5f);

HostContainer-&gt;CurrentSpriteBatch-&gt;Draw(
    m_body.Get(),
    Position,
    PositionUnits::DIPs,
    float2(400.0f, 400.0f) * Scale,
    SizeUnits::Pixels,
    m_shading,
    Rotation);

HostContainer-&gt;CurrentSpriteBatch-&gt;Draw(
    m_leftPaw.Get(),
    m_leftPawPosition,
    PositionUnits::DIPs,
    float2(522.0f, 141.0f) * Scale,
    SizeUnits::Pixels,
    m_shading,
    m_leftPawRotation &#43; 0.5f);
</pre></p><p>Let’s take a look at how the position and rotation values are modified. All item animations are performed with the help of timers set to brief intervals in which the values are cycled through two value exchange operations. Here is a snippet taken from inside the Update method in the <strong>GameBear</strong> class that is responsible for bear arm movement:</p><p><pre class="brush: cpp">
if (m_armRotationTimer &lt; 0.6f)
{
    m_rightPawRotation -= 0.005f;
    m_leftPawRotation &#43;= 0.005f;
}
else if (m_armRotationTimer &gt; 0.6f &amp;&amp; m_armRotationTimer &lt; 1.2f)
{
    m_rightPawRotation &#43;= 0.005f;
    m_leftPawRotation -= 0.005f;
}
else
{
    m_rightPawRotation = 0.0f;
    m_leftPawRotation = 0.0f;
    m_armRotationTimer = 0.0f;
}
</pre></p><p><strong>m_armRotationTimer</strong> is a float value that is initially set to <strong>0.0f</strong>. In the <strong>Update</strong> loop and increments each iteration by the value of <strong>timeDelta</strong>, which represents the time difference between two loop cycles. As this value is less than 600 milliseconds (0.6 seconds), the right paw rotation is incremented and the left paw rotation decremented. The difference in the value adjustment direction is caused by the fact that one paw is rotated clockwise and the other is rotated counterclockwise. Once the timer tracks a value above 600 milliseconds but below than 1200 milliseconds, the process reverses and the paws rotate in the opposite direction. After 1.2 seconds, the timer resets, as does the rotation.</p><p>Since this rotation is automated, <strong>GameBear-&gt;Update</strong> is called in the menu screen:</p><p><pre class="brush: cpp">
m_showBear-&gt;Update(timeTotal, timeDelta, float2(Manager-&gt;m_windowBounds.Width / 2, Manager-&gt;m_windowBounds.Height / 2));
</pre></p><p>Outside the context of the bear update cycle, there is a similar timed mechanism used to randomly move the bear across the screen:</p><p><pre class="brush: cpp">
if (m_positionYAdj == 0.0f)
{
    m_positionYAdj = RandFloat(0.1f, 1.2f);
    m_positionXAdj = RandFloat(-1.0f, 1.0f);
}

if (m_positionTimer &lt; 4.0f)
{
    m_showBear-&gt;Position.x &#43;= m_positionXAdj;
    m_showBear-&gt;Position.y &#43;= m_positionYAdj;
    m_showBear-&gt;Rotation &#43;= 0.001f;
    m_showBear-&gt;Scale &#43;= 0.0008f;
    
    m_showMonster-&gt;Scale &#43;= 0.002f;
}
else if (m_positionTimer &gt; 4.0f &amp;&amp; m_positionTimer &lt; 8.0f)
{
    m_showBear-&gt;Position.x -= m_positionXAdj;
    m_showBear-&gt;Position.y -= m_positionYAdj;
    m_showBear-&gt;Rotation -= 0.001f;
    m_showBear-&gt;Scale -= 0.0008f;
}
else
{
    m_positionYAdj = 0.0f;
    m_positionTimer = 0.0f;
}
</pre></p><p>The X and Y adjustments are randomly generated and for the duration of a single timer cycle (in this case, 4 seconds) the bear’s horizontal and vertical positions are adjusted using those values. The rotation and scale are minimally adjusted to create a 3D motion effect. Because the displacement is minimal, the bear is always visible and does not move much outside the viewport.</p><p>There is also a flying monster animation in the main menu screen. Monster creation happens on top of the same instance that is replaced when an initial monster flies out of bounds:</p><p><pre class="brush: cpp">
m_showMonster-&gt;Position.y -= m_showMonster-&gt;Velocity.y;
if (m_showMonster-&gt;Position.y &lt; -m_showMonster-&gt;Size.y)
{
    CreateNewMonster();
}
</pre></p><p>&nbsp;</p><p>When a new monster is created, a random monster type is selected and its position on the X axis is randomized. The Y position is set to be right under the bottom screen boundary:</p><p><pre class="brush: cpp">
void MenuScreen::CreateNewMonster()
{
    m_showMonster = ref new Monster(this, (MonsterType)(rand() % (int)MonsterType::MT_CANDYLAND_E), true);
    m_showMonster-&gt;Scale = 0.3f;
    m_showMonster-&gt;Velocity.y = 1.0f;
    m_showMonster-&gt;Load();
    m_showMonster-&gt;Position = float2(RandFloat(LoBoundX, HiBoundX), Manager-&gt;m_windowBounds.Height &#43; m_showMonster-&gt;Size.y * m_showMonster-&gt;Scale);
}
</pre></p><p>Monster scaling is done on the same timed loop as the bear. The results look like this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-9.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B1%5D-6.png" alt="image" width="640" height="362" border="0"></a></p><h3>Gameplay Screen</h3><h4>Bear</h4><p>The gameplay screen carries the most animations in FallFury, including animations related to ammo displacement, monster movement paths, power-up animations, and secondary game character animations that are triggered in special cases such as character death.</p><p>Let’s start with character entrance. When the game begins, the teddy bear falls into the screen and stops at a specific point close to the top boundary of the gameplay screen. Once that transition is complete, the bear is no longer vertically displaced:</p><p><pre class="brush: cpp">
if ((GameBear-&gt;Position.y / HiBoundY) &lt; 0.19f)
{
    GameBear-&gt;Position.y &#43;= GameBear-&gt;Velocity.y * (3.2f);
}
</pre></p><p>&nbsp;</p><p>If the limit is not hit, the original bear velocity is multiplied by a fixed value, after which the condition is ignored for the rest of the gameplay.</p><p>Let’s now take a look at what happens when an enemy shell kills the bear. Generally, when the main character is killed, there is not much sense in maintaining other in-game activities. In FallFury, a killed bear results in a time freeze—the fall stops and the monsters are no longer shooting or moving. Not only that, but the bear is also flipped on its back:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B11%5D-3.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B3%5D-8.png" alt="image" width="386" height="387" border="0"></a></p><p>In the <strong>Update</strong> loop, the position for the paws and the head are adjusted for the new body texture layout:</p><p><pre class="brush: cpp">
if (IsDead)
{
    if (m_armRotationTimer &lt; 1.0f)
    {
        m_rightPawRotation &#43;= 0.001f;
        m_leftPawRotation -= 0.001f;
    }
    else if (m_armRotationTimer &gt; 1.0f &amp;&amp; m_armRotationTimer &lt; 2.0f)
    {
        m_rightPawRotation -= 0.001f;
        m_leftPawRotation &#43;= 0.001f;
    }
    else
    {
        m_rightPawRotation = 0.0f;
        m_leftPawRotation = 0.0f;
        m_armRotationTimer = 0.0f;
    }

    m_rightPawPosition = Position &#43; float2(40.0f, -50.0f) * Scale;
    m_leftPawPosition = Position &#43; float2(10.0f, 150.0f) * Scale;
    m_headPosition = (Position - float2(-160.0f, 0.0f) * Scale);
}
</pre></p><p>The proper textures are assigned via the <strong>Kill</strong> method:</p><p><pre class="brush: cpp">
void Bear::Kill()
{
    IsDead = true;
    Rotation = -1.0f;
    m_head = m_deadHead;
    m_body = m_deadBody;
    m_leftPaw = m_deadLeftArm;
    m_rightPaw = m_deadRightArm;
}
</pre></p><p>The bear will continue falling as long as <strong>StopBackground</strong> in <strong>GamePlayScreen</strong> is called:</p><p><pre class="brush: cpp">
void GamePlayScreen::StopBackground()
{
    m_isBackgroundMoving = false;
}
</pre></p><p>This will cause the internal state check to fail in the <strong>Update</strong> loop, sending the bear off screen limits. Once the bear completes the fall, the state is set to <strong>GS_GAME_OVER</strong>:</p><p><pre class="brush: cpp">
if (!m_isBackgroundMoving)
{
    if (GameBear-&gt;Position.y &gt; m_screenSize.y)
    {
        Manager-&gt;CurrentGameState = GameState::GS_GAME_OVER;
    }
    else
    {
        GameBear-&gt;Position.y &#43;= GameBear-&gt;Velocity.y * 1.5f;
    }
}
</pre></p><h4>Monsters</h4><p>Monsters, on the other hand, are being constantly moved during the duration of the game. Their basic displacement is performed by MoveMonsters:</p><p><pre class="brush: cpp">
void GamePlayScreen::MoveMonsters(float timeTotal ,float timeDelta)
{
    for (auto monster = m_monsters.begin(); monster != m_monsters.end();)
    {
        Monster^ currentMonster = (*monster);
        if ((currentMonster-&gt;Position.y - GameBear-&gt;Position.y) &lt; -Manager-&gt;m_renderTargetSize.Height / 2)
        {
            monster = m_monsters.erase(monster);
        }
        else
        {
            currentMonster-&gt;Velocity.y = GameBear-&gt;Velocity.y;
            currentMonster-&gt;Update(timeTotal, timeDelta, GameBear-&gt;Position, GetScreenBounds());
            CheckForCollisionWithAmmo(currentMonster);
            &#43;&#43;monster;
        }
    }
}
</pre></p><p>This method adjusts the monster position relative to the bear:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B14%5D-3.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B4%5D-2.png" alt="image" width="622" height="349" border="0"></a></p><p>The zig-zag like motion is defined in the <strong>Monster</strong> class in the <strong>Update</strong> method:</p><p><pre class="brush: cpp">
float adjustment = 0.0f;
adjustment = m_goingRight ? Position.x &#43; Velocity.x : Position.x - Velocity.x;
if (adjustment &gt;= (HostContainer-&gt;LoBoundX &#43; (Size.x * Scale) / 2.0f) 
&amp;&amp; adjustment &lt;= (HostContainer-&gt;HiBoundX - (Size.x * Scale) / 2.0f))
{
    Position.x = adjustment;
}
else
{
    m_goingRight = !m_goingRight;
}
</pre></p><p>&nbsp;</p><p>The snippet above determines the direction in which the enemy has to move depending on which screen boundary is hit first. While the monster is active and is visible, its vertical adjustment is performed in a timed loop, like this:</p><p><pre class="brush: cpp">
m_jumpingTimer &#43;= timeDelta;
if (m_jumpingTimer &gt; 0.0f &amp;&amp; m_jumpingTimer &lt; 1.0f)
{
    Position.y -= 1.0f;
}
else if (m_jumpingTimer &gt;= 1.0f &amp;&amp; m_jumpingTimer &lt; 2.0f)
{
    Position.y &#43;= 1.0f;
}
else
{
    m_jumpingTimer = 0.0f;
}
</pre></p><p>Here you can either use the Y velocity or introduce a static value. The only condition has to be a number low enough that the monster does not leave the screen, which would prevent the bear from being able to kill it. When the monster is killed, it flies out by following an arch-like path:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B17%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B5%5D-1.png" alt="image" width="487" height="480" border="0"></a></p><p>The “death arc” is implemented via another timer:</p><p><pre class="brush: cpp">
Position.x &#43;= Velocity.y * 1.3f;
if (m_deathArcTimer &gt; 0.4f)
{
    Position.y &#43;= Velocity.y;
    if (Scale &gt; 0.1f)
    Scale -= 0.01f;
}
else
{
    Position.y -= Velocity.y;
    Scale &#43;= 0.01f;
    m_deathArcTimer &#43;= timeDelta;
}
</pre></p><p>&nbsp;</p><p>Regardless of the monster position, the horizontal displacement is positive and the entity moves to the right. For 400 milliseconds its vertical position is decreased, moving the texture up, and the scale is also adjusted to create the proximity effect. After this time interval, the monster drops out of the screen boundaries.</p><p>As previously mentioned, each monster is composed of three cycled textures, which are loaded and stored in three ID3D11Texture2D containers:</p><p><pre class="brush: cpp">
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt; m_spriteA;
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt; m_spriteB;
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt; m_spriteC;
</pre></p><p>&nbsp;</p><p>Each of these is assigned to the main body texture container every 300 milliseconds, replacing the previously assigned asset:</p><p><pre class="brush: cpp">
m_stateChangeTimer &#43;= timeDelta;
if (m_stateChangeTimer &lt; 0.3f)
{
    m_body = m_spriteA;
}
else if (m_stateChangeTimer &gt; 0.3f &amp;&amp; m_stateChangeTimer &lt; 0.6f)
{
    m_body = m_spriteB;
}
else if (m_stateChangeTimer &gt; 0.6f &amp;&amp; m_stateChangeTimer &lt; 0.9f)
{
    m_body = m_spriteC;
}
else if (m_stateChangeTimer &gt; 0.9f)
{
    m_stateChangeTimer = 0.0f;
}
</pre></p><p>&nbsp;</p><p>This cycle can be disabled when the monster is not active.</p><h4>Ammo</h4><p>There are different types of ammo used in the game, and each behaves in its own way. The stock ammo type is a plasma ball.</p><p>The default shooting behavior releases a shell when the user taps anywhere on the screen (other than the pause button area). Given the texture of the shell, when it is released the tail must be oriented towards the bear at an angle equal to the one created by the bear and the target position. To get a better idea, take a look at the images below:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B20%5D-4.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B6%5D-5.png" alt="image" width="339" height="340" border="0"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B23%5D-1.png">&nbsp;<img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B7%5D-3.png" alt="image" width="340" height="340" border="0"></a></p><p>In the image on the left, the player tapped at the bottom of the screen. In the one on the right, the player tapped at the right edge of the screen. The shell accordingly rotates depending on the tapped position. To get a better understanding of how the rotation is performed, imagine the XY coordinate grid with the bear located at the intersection of the axes:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B26%5D-2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B8%5D-7.png" alt="image" width="622" height="279" border="0"></a></p><p>Thinking back to trigonometry, notice the triangle formed by the shell and the bear origin point:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B29%5D-3.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B9%5D-2.png" alt="image" width="288" height="182" border="0"></a></p><p>Remember also the trig concept of quadrants:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B32%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B10%5D-5.png" alt="image" width="623" height="278" border="0"></a></p><p>The quadrant in which the shell is located determines how the angle is calculated and the tail rotated. If the shell is in quadrant 2 or 3, calculate the rotation radians by following this algorithm:</p><p>1. Find the hypotenuse from the X and Y components of the velocity, which can be calculated by finding the difference between the bear and the position of the tap. To do this, us the well-known Pythagorean theorem:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B35%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B11%5D-2.png" alt="image" width="100" height="20" border="0"></a></p><p>The hypotenuse formula can be deduced from the formula above and is the square root of the sum of the velocity component squares:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B38%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B12%5D-5.png" alt="image" width="114" height="21" border="0"></a></p><p>2. Once calculated, it is necessary to find the sine of the target angle. The value can be obtained by dividing the Y component of the velocity by the hypotenuse.</p><p>3. Find the angle by calculating the arcsine from the resultant sine value. This will return the final angle in radians.</p><p>That said, for shells launched in quadrants 1 or 4, there is one extra step that needs to be performed. In addition to the rotation value obtained from the steps listed above, the rotation should be incremented by the radian value of a 180-degree angle minus twice the rotation value previously obtained. This ensures that the tail is correctly flipped relative to the axis origin.</p><p>In C&#43;&#43;, the implementation is done inside the <strong>AmmoItem</strong> class. For flexibility purposes, it triggers inside the <strong>Update</strong> loop—that way, it is possible to modify the trajectory of the shell and not worry about turning it again manually after launch:</p><p><pre class="brush: cpp">
if ((Velocity.x &gt; 0 &amp;&amp; Velocity.y &gt; 0) || (Velocity.x &gt; 0 &amp;&amp; Velocity.y &lt;0))
{
    Rotation = CalculateRadians(Velocity);
    Rotation &#43;= CalculateRadiansFromAngle(180) - 2 * Rotation;
}
else
{
    Rotation = CalculateRadians(Velocity);
}
</pre></p><p><strong>CalculateRadians</strong> is the method that transforms the velocity components in a rotation value. It is located in the <strong>BasicMath.h </strong>helper:</p><p><pre class="brush: cpp">
inline float CalculateRadians(float2 velocity)
{
    float hypothenuse = sqrt(velocity.x * velocity.x &#43; velocity.y * velocity.y);
    float sine = velocity.y / hypothenuse;
    float angle = asin(sine);
    return angle;
};
</pre></p><p>&nbsp;</p><p>There is a potential problem with the implementation above. As the user taps on different parts of the screen, the X and Y components are different, each resulting in a different hypotenuse. As the target is set, the shell flies faster the further away from the bear the user taps. To avoid this, the triangle legs should be normalized to a near-constant value:</p><p>Take a look at the <strong>ShootAtTarget</strong> function in the Bear class:</p><p><pre class="brush: cpp">
void Bear::ShootAtTarget(float2 lastTargetTrace)
{
    OnPulledTrigger(Position.x, Position.y, 
    GetVelocityLegs(lastTargetTrace).x, GetVelocityLegs(lastTargetTrace).y, 
    CurrentDamage, IsFriendly, false, HostContainer-&gt;CurrentSpriteBatch);
}
</pre></p><p>&nbsp;</p><p>Notice that the triangle legs are not passed as a raw value, but are proxied through <strong>GetVelocityLegs</strong>, which forces the resulting vector to be produced from a constant triangle with the velocity constant at 10 pixels per iteration:</p><p><pre class="brush: cpp">
float2 LivingEntity::GetVelocityLegs(float2 lastTargetTrace)
{
    float bottomLeg = 0.0f;
    float sideLeg = (Position.y - lastTargetTrace.y) / 100.0f;
    bottomLeg = (Position.x - lastTargetTrace.x) / 100.0f;
    float requiredVelocity = 10.0f;
    float hypothenuse = sqrt(bottomLeg * bottomLeg &#43; sideLeg * sideLeg);
    float proportionalX = 0.0f;
    float proportionalY = 0.0f;
    proportionalX = (requiredVelocity * bottomLeg) / hypothenuse;
    proportionalY = (sideLeg &lt; 0.0f ? -1 : 1) * sqrt(requiredVelocity * requiredVelocity - proportionalX * proportionalX);
    return float2(proportionalX,proportionalY);
}
</pre></p><p>&nbsp;</p><p>For ammo that does not have a visual rotation dependency, such as the plasma ball, simply increment the rotation to make the thrown item continuously spin:</p><p><pre class="brush: cpp">
if (Type == PowerupType::PLASMA_BALL)
{
    if ((Velocity.x &gt; 0 &amp;&amp; Velocity.y &gt; 0) || (Velocity.x &gt; 0 &amp;&amp; Velocity.y &lt;0))
    {
        Rotation = CalculateRadians(Velocity);
        Rotation &#43;= CalculateRadiansFromAngle(180) - 2 * Rotation;
    }
    else
    {
        Rotation = CalculateRadians(Velocity);
    }
}
else
{
    Rotation &#43;= 0.2f;
}
</pre></p><p>&nbsp;</p><h3>Conclusions</h3><p>FallFury mostly relies on sprite-based animations in which there are several textures cycled through in order to create the desired dynamic effect. These are not really hard to build, given that there is a possibility to integrate them in a timed loop. Be aware, however, that with slower machines the timing might be off and the time delta value between loops might be higher. In that case the sprite cycling will not be as smooth as it should be, which is why it’s important to perform animation testing on a variety of hardware with different OS loads.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:cf9dec8e099f4f63a437a14d0152aeab">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations</comments>
      <itunes:summary>Animations &amp;amp; Item TransitionsFallFury relies on a lot of dynamic content. As you already aware of how SpriteBatch is invoked inside the FallFury rendering stack, this article focuses on how dynamic activities are handled on existing textures and entities. If you need a quick look at what was already covered, refer to Part 3 of the series. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-7-Animations&amp;nbsp;. For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Menu ScreenThe first animated element shown in the menu screen is the bear, which is positioned in the top half of the viewport. Notice that the bear moves its paws as well as moving across the screen:  The bear is implemented in the GameBear class and is the normal playable entity that is invincible when animated outside the scope of the gameplay screen. Its full body image is composed of four textures: 
Microsoft::WRL::ComPtr&amp;lt;ID3D11Texture2D&amp;gt;        m_head;
Microsoft::WRL::ComPtr&amp;lt;ID3D11Texture2D&amp;gt;        m_leftPaw;
Microsoft::WRL::ComPtr&amp;lt;ID3D11Texture2D&amp;gt;        m_rightPaw;

Microsoft::WRL::ComPtr&amp;lt;ID3D11Texture2D&amp;gt;        m_body // Exposed through LivingEntity;
 Each of these textures is internally dependent on the coupled float rotation and position values passed to the sprite batch in the host container (the parent screen): 
HostContainer-&amp;gt;CurrentSpriteBatch-&amp;gt;Draw(
    m_rightPaw.Get(),
    m_rightPawPosition,
    PositionUnits::DIPs,
    float2(522.0f, 141.0f) * Scale,
    SizeUnits::Pixels,
    m_shading,
    m_rightPawRotation - 0.5f);

HostContainer-&amp;gt;CurrentSpriteBatch-&amp;gt;Draw(
    m_body.Get(),
    Position,
    PositionUnits::DIPs,
    float2(400.0f, 400.0f) * Scale,
    SizeUnits::Pixels,
    m_shading,
    Rotation);

HostContainer-&amp;gt;CurrentSpriteBatch-&amp;gt;Draw(
    m_leftPaw.Get(),
    m_leftPawPosition,
    PositionUnits::DIPs,
    float2(522</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations</link>
      <pubDate>Wed, 23 Jan 2013 23:57:22 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/5a90/d869aabf-608a-42a9-b8b5-3512c3e65a90/FallFuryPart7_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-7-Animations/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 6 - Rendering Level Elements</title>
      <description><![CDATA[<h4>Rendering Level Elements</h4><p>In the previous article, you learned how to build level XML files in order to create playable levels. This article discusses how the internal parser works and how XML nodes become items on the game screen.&nbsp; Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements">http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Project Interop – The C# Parser</h4><p>Thanks to classes such as <a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx">XmlSerializer</a> and <a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx">XDocument</a>, parsing XML in .NET Framework is not a complicated task. Similarly, in the WinRT world there are alternatives such as <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.data.xml.dom.aspx">Windows::Data::Xml::Dom</a>. That being said, using the parser skeleton in C# this project leverages the existing codebase, adapting it to the specific level reading needs.</p><p>Start by creating a new WinRT project that is the part of the existing solution. Make sure that you create a Windows Runtime Component:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-5.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-6.jpg" alt="clip_image002" width="624" height="380" border="0"></a></p><p>There are <a href="http://www.drdobbs.com/windows/winrt-the-new-runtime-in-windows-8/232200577">major differences</a> between the .NET and WinRT stacks, especially when it comes to building code that can be invoked from any potential WinRT project type, as is the case here. Make sure that the output of the newly created project is a Windows Runtime Component (<a href="http://www.thomgerdes.com/2011/12/winrt-internals-winmd-files.html">WinMD file</a>):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-3.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-4.jpg" alt="clip_image004" width="640" height="195" border="0"></a></p><p>The XMLReader project reads much more than the level data—it also manages internal XML metadata such as user scores. This article, however, focuses only on level-related aspects of the engine.</p><p><strong>Reader </strong>is the one core class used here. It contains the <strong>ReadXml</strong> method, which receives the file name and the type of the XML file to be read. Regardless of the name, the XML file type determines the parsing rules, the root lookup location, and the produced output. The tier (level set) and individual level data are stored internally in the application folder, and the score metadata is outside the sandbox in the application data folder:</p><p><pre class="brush: csharp">
async Task&lt;Object&gt; ReadXml(string fileName, XmlType type)
{
        StorageFile file = null;
        StorageFolder folder = null;
    
        if (type == XmlType.LEVEL || type == XmlType.TIERS)
        {
                folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
                folder = await folder.GetFolderAsync(&quot;Levels&quot;);
        }
        else if (type == XmlType.HIGHSCORE)
        {
                folder = ApplicationData.Current.LocalFolder;
                folder = await folder.GetFolderAsync(&quot;Meta&quot;);
        }
    
        file = await folder.GetFileAsync(fileName);
    
        Object returnValue = null;
        string data;
    
        using (IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read))
        {
                using (Stream inStream = Task.Run(() =&gt; readStream.AsStreamForRead()).Result)
                {
                        using (StreamReader reader = new StreamReader(inStream))
                        {
                                data = reader.ReadToEnd();
                        }
                }
        }
    
        if (type == XmlType.LEVEL)
        {
                returnValue = ExtractLevelData(data);
        }
        else if (type == XmlType.HIGHSCORE)
        {
                returnValue = ExtractScoreData(data);
        }
        else if (type == XmlType.TIERS)
        {
                returnValue = ExtractTierData(data);
        }
    
        return returnValue;
}
</pre></p><p>Before the level data is extracted, FallFury needs to know about the existing tiers pointing to those levels. That’s where <strong>ExtractTierData</strong>, an internal method that accepts a raw XML string and return a <strong>TierSet</strong> instance, comes in:</p><p><pre class="brush: csharp">
public sealed class TierSet
{
    public Tier[] Tiers { get; set; }
}
</pre></p><p>A <strong>Tier</strong> class has the following structure:</p><p><pre class="brush: csharp">
public sealed class Tier
{
    public string Name { get; set; }
    public string[] LevelNames { get; set; }
    public string[] LevelFiles { get; set; }
}
</pre></p><p>I am using the most fundamental types – arrays instead of generic collections, to maximize the portability of the code. The <strong>ExtractTierData </strong>method handles the XML-to-Object transformation:</p><p><pre class="brush: csharp">
TierSet ExtractTierData(string tierString)
{
        TierSet set = new TierSet();
    
        XDocument document = XDocument.Parse(tierString);
    
        set.Tiers = new Tier[document.Root.Elements().Count()];
    
        int tierCounter = 0;
    
        foreach (XElement element in document.Root.Elements())
        {
                Tier tier = new Tier();
                tier.Name = element.Attribute(&quot;name&quot;).Value;
        
                tier.LevelFiles = new string[element.Elements(&quot;level&quot;).Count()];
                tier.LevelNames = new string[element.Elements(&quot;level&quot;).Count()];
        
                
                int count = 0;
                foreach (XElement lElement in element.Elements(&quot;level&quot;))
                {
                        tier.LevelFiles[count] = lElement.Attribute(&quot;file&quot;).Value;
                        tier.LevelNames[count] = lElement.Attribute(&quot;name&quot;).Value;
                        count&#43;&#43;;
                }
        
                set.Tiers[tierCounter] = tier;
                tierCounter&#43;&#43;;
        }
    
        return set;
}
</pre></p><p>I am running a coupled array block here, utilizing one array for level names and another for file locations. This is a very basic implementation of a key-value pair that depends on code-based coupling. <strong>ExtractTierData</strong>, however, is not exposed publicly and the C&#43;&#43; layer of FallFury will not access it because <strong>TierSet</strong> is not exposed through a compatible async method. Looking back at <strong>ReadXml</strong>, might seem like the answer to this problem. But a <strong>Task&lt;Object&gt;</strong> is not an interop-compatible type, which means I use <strong>ReadXmlAsync</strong>, which proxies the call through an <a href="http://msdn.microsoft.com/en-us/library/windows/apps/br206598.aspx">IAsyncOperation</a>:</p><p><pre class="brush: csharp">
public IAsyncOperation&lt;Object&gt; ReadXmlAsync(string filename, XmlType type)
{
    return (IAsyncOperation&lt;Object&gt;)AsyncInfo.Run((CancellationToken token) =&gt; ReadXml(filename, type));
}
</pre></p><p><a href="http://msdn.microsoft.com/en-us/library/hh779740.aspx">AsyncInfo.Run</a> starts a WinRT async operation and handles the returned result, regardless of the selected file path or type.</p><p>Level-based data is extracted in a similar manner to the tier data. The difference lies in the used internal models, as well as the node reading order:</p><p><pre class="brush: csharp">
Level ExtractLevelData(string levelString)
{
        XDocument document = XDocument.Parse(levelString);
    
        Level level = new Level();
        level.LevelMeta = new Meta();
     
        level.LevelMeta.Score = Convert.ToInt32(document.Root.Element(&quot;meta&quot;).Attribute(&quot;score&quot;).Value);
        level.LevelMeta.ButtonPrice = Convert.ToInt32(document.Root.Element(&quot;meta&quot;).Attribute(&quot;buttonPrice&quot;).Value)
        level.LevelMeta.LevelType = (LevelType)Convert.ToInt32(document.Root.Attribute(&quot;type&quot;).Value);
    
        int count = document.Root.Element(&quot;obstacles&quot;).Elements().Count();
        level.Obstacles = new Obstacle[count];
    
        count = 0;
        foreach (XElement element in document.Root.Element(&quot;obstacles&quot;).Elements())
        {
                Obstacle obstacle = new Obstacle();
                obstacle.HealthDamage = Convert.ToSingle(element.Attribute(&quot;healthDamage&quot;).Value);
                obstacle.InflictsDamage = Convert.ToBoolean(element.Attribute(&quot;inflictsDamage&quot;).Value);
                obstacle.Rotation = Convert.ToSingle(element.Attribute(&quot;rotation&quot;).Value);
                obstacle.Scale = Convert.ToSingle(element.Attribute(&quot;scale&quot;).Value);
                obstacle.X = Convert.ToSingle(element.Attribute(&quot;x&quot;).Value);
                obstacle.Y = Convert.ToSingle(element.Attribute(&quot;y&quot;).Value);
                obstacle.Type = (ObstacleType)Convert.ToInt32(element.Attribute(&quot;type&quot;).Value);
                level.Obstacles[count] = obstacle;
                count&#43;&#43;;
        }
    
        count = document.Root.Element(&quot;monsters&quot;).Elements().Count();
        level.Monsters = new Monster[count];
    
        count = 0;
        foreach (XElement element in document.Root.Element(&quot;monsters&quot;).Elements())
        {
                Monster monster = new Monster();
                monster.CriticalDamage = Convert.ToSingle(element.Attribute(&quot;criticalDamage&quot;).Value);
                monster.Damage = Convert.ToSingle(element.Attribute(&quot;damage&quot;).Value);
                monster.DefaultAmmo = Convert.ToInt32(element.Attribute(&quot;defaultAmmo&quot;).Value);
                monster.MaxHealth = Convert.ToSingle(element.Attribute(&quot;maxHealth&quot;).Value);
                monster.X = Convert.ToSingle(element.Attribute(&quot;x&quot;).Value);
                monster.Y = Convert.ToSingle(element.Attribute(&quot;y&quot;).Value);
                monster.VelocityX = Convert.ToSingle(element.Attribute(&quot;velocityX&quot;).Value);
                monster.Lifetime = Convert.ToSingle(element.Attribute(&quot;lifetime&quot;).Value);
                monster.Type = (MonsterType)Convert.ToInt32(element.Attribute(&quot;type&quot;).Value);
                monster.Bonus = Convert.ToInt32(element.Attribute(&quot;bonus&quot;).Value);
                monster.Scale = Convert.ToSingle(element.Attribute(&quot;scale&quot;).Value);
        
                level.Monsters[count] = monster;
                count&#43;&#43;;
        }
    
        count = document.Root.Element(&quot;buttons&quot;).Elements().Count();
        level.Buttons = new Button[count];
    
        count = 0;
        foreach (XElement element in document.Root.Element(&quot;buttons&quot;).Elements())
        {
                Button button = new Button();
        
                button.X = Convert.ToSingle(element.Attribute(&quot;x&quot;).Value);
                button.Y = Convert.ToSingle(element.Attribute(&quot;y&quot;).Value);
        
                level.Buttons[count] = button;
                count&#43;&#43;;
        }
    
        count = document.Root.Element(&quot;powerups&quot;).Elements().Count();
        level.Powerups = new Powerup[count];
    
        count = 0;
        foreach (XElement element in document.Root.Element(&quot;powerups&quot;).Elements())
        {
                Powerup powerup = new Powerup();
        
                powerup.X = Convert.ToSingle(element.Attribute(&quot;x&quot;).Value);
                powerup.Y = Convert.ToSingle(element.Attribute(&quot;y&quot;).Value);
                powerup.Category = (PowerupCategory)Convert.ToInt32(element.Attribute(&quot;category&quot;).Value);
                powerup.Type = (PowerupType)Convert.ToInt32(element.Attribute(&quot;type&quot;).Value);
                powerup.Lifespan = Convert.ToSingle(element.Attribute(&quot;lifespan&quot;).Value);
                powerup.Effect = Convert.ToSingle(element.Attribute(&quot;effect&quot;).Value);
        
                level.Powerups[count] = powerup;
                count&#43;&#43;;
        }
    
        Bear bear = new Bear();
        XElement bearElement = document.Root.Element(&quot;bear&quot;);
        bear.CriticalDamage = Convert.ToSingle(bearElement.Attribute(&quot;criticalDamage&quot;).Value);
        bear.Damage = Convert.ToSingle(bearElement.Attribute(&quot;damage&quot;).Value);
        bear.DefaultAmmo = Convert.ToInt32(bearElement.Attribute(&quot;defaultAmmo&quot;).Value);
        bear.MaxHealth = Convert.ToSingle(bearElement.Attribute(&quot;maxHealth&quot;).Value);
        bear.StartPosition = Convert.ToSingle(bearElement.Attribute(&quot;startPosition&quot;).Value);
        bear.Velocity = Convert.ToSingle(bearElement.Attribute(&quot;velocity&quot;).Value);
    
        level.GameBear = bear;
        
        return level;
}
</pre></p><p>As a result, the <strong>Level</strong> instance has an internal counterpart in the C&#43;&#43; project:</p><p><pre class="brush: csharp">
public sealed class Level
{
    public Bear GameBear { get; set; }
    public Meta LevelMeta { get; set; }
    public Obstacle[] Obstacles { get; set; }
    public Monster[] Monsters { get; set; }
    public Button[] Buttons { get; set; }
    public Powerup[] Powerups { get; set; }
}
</pre></p><h4>From C# to C&#43;&#43; - Leveraging the WinRT Component</h4><p>At this point, the C#-based WinRT component is complete and can be integrated into the C&#43;&#43; project. This can be done in two ways: either by adding a reference to the project itself or by adding a reference to the generated WinMD file. Both methods will ultimately produce the same output, but it’s easier to debug and modify coupled projects on the go, so I went with the first option.</p><p>To add a reference to an internal Windows Runtime Component project, right click on the C&#43;&#43; project in <strong>Solution Explorer</strong> and select <strong>Properties</strong>. You will see a dialog like this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D-1.jpg"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb-2.jpg" alt="clip_image006" width="567" height="403" border="0"></a></p><p>Select the <strong>Common Properties</strong> node in the tree on the left and open the <strong>Framework and References</strong> page:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B3%5D-2.jpg"><img title="clip_image008" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008_thumb-3.jpg" alt="clip_image008" width="569" height="404" border="0"></a></p><p>In the sample screen capture above, the <strong>FallFury.XMLReader</strong> project is already added as a reference. For a new project, simply click on <strong>Add New Reference</strong> and add any compatible project or third-party extension. As soon as the reference is added, the publicly exposed methods can be accessed.</p><p>In <strong>DirectXPage.cpp</strong> I have a method called <strong>LoadLevelData</strong> that allows me to load the list of the registered levels from <strong>core.xml</strong> as well as build the visual tree for the menu items, whichallows players to select a level:</p><p><pre class="brush: cpp">
void DirectXPage::LoadLevelData()
{
    Coding4Fun::FallFury::XMLReader::Reader^ reader = ref new Coding4Fun::FallFury::XMLReader::Reader();
    Windows::Foundation::IAsyncOperation&lt;Platform::Object^&gt;^ result = reader-&gt;ReadXmlAsync(&quot;core.xml&quot;, Coding4Fun::FallFury::XMLReader::Models::XmlType::TIERS);
    result-&gt;Completed =
        ref new AsyncOperationCompletedHandler&lt;Platform::Object^&gt;(this, &amp;DirectXPage::OnLevelLoadCompleted);
}
</pre></p><p>Following the normal asynchronous pattern, as well as the structure of the method exposed in the Reader class, I am calling <strong>ReadXmlAsync</strong> and getting the result in <strong>OnLevelLoadCompleted</strong> when the operation reaches its final stage. It is worth mentioning that the associated <a href="http://msdn.microsoft.com/en-us/library/windows/apps/br206572.aspx">AsyncOperationCompletedHandler</a> is invoked even when the reading fails; therefore, the invocation of that callback does not on its own mean that the necessary data is obtained:</p><p>Here is what happens when <strong>OnLevelLoadCompleted</strong> is called:</p><p><pre class="brush: cpp">
void DirectXPage::OnLevelLoadCompleted(IAsyncOperation&lt;Platform::Object^&gt; ^op, AsyncStatus s)
{
    if (s == AsyncStatus::Completed)
    {
        auto set = (Coding4Fun::FallFury::XMLReader::Models::TierSet^)op-&gt;GetResults();
        
        auto tiers = set-&gt;Tiers;
        
        int levelCounter = 0;
        
        for (auto tier = tiers-&gt;begin(); tier != tiers-&gt;end(); tier&#43;&#43;)
        {
            StackPanel^ panel = ref new StackPanel();
            
            TextBlock^ levelTierTitle = ref new TextBlock();
            levelTierTitle-&gt;Text = (*tier)-&gt;Name;
            levelTierTitle-&gt;Style = (Windows::UI::Xaml::Style^)Application::Current-&gt;Resources-&gt;Lookup(&quot;LevelSelectTierItemText&quot;);
            levelTierTitle-&gt;RenderTransform = ref new TranslateTransform();
            panel-&gt;Children-&gt;Append(levelTierTitle);
            
            levelNames = (*tier)-&gt;LevelNames;
            auto levelFiles = (*tier)-&gt;LevelFiles;
            
            int max = levelNames-&gt;Length;
            
            for(int i = 0; i &lt; max; i&#43;&#43;)
            {
                MenuItem^ item = ref new MenuItem();
                item-&gt;Tag = levelCounter;
                item-&gt;Label = levelNames[i];
                item-&gt;HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Left;
                item-&gt;OnButtonSelected &#43;= ref new MenuItem::ButtonSelected(this, &amp;DirectXPage::OnLevelButtonSelected);
                item-&gt;RenderTransform = ref new TranslateTransform();
                
                m_renderer-&gt;Levels.Insert(levelCounter,levelFiles[i]);
                
                panel-&gt;Children-&gt;Append(item);
                levelCounter&#43;&#43;;
            }
            
            stkLevelContainer-&gt;Items-&gt;Append(panel);
        }
    }
}
</pre></p><p>Here, <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.foundation.asyncstatus">AsyncStatus</a> can also be <strong>Cancelled</strong> or <strong>Error</strong>, so checking for <strong>Complete</strong> ensures that the expected result is processed further inside the context of the callback.</p><p>As the returned <strong>TierSet</strong> exposes the <strong>Tiers</strong> array, I am simply iterating through each of the existing items to create independent tier blocks, grouped in <strong>StackPanel</strong> elements, coupled with level-specific <strong>MenuItem</strong> instances that present the user with a choice of playing a given level. The level ID is carried in the Tag property and it will be used to identify the selected button when <strong>DirectXPage::OnLevelButtonSelected</strong> is triggered:</p><h4>Reading Level-specific Data</h4><p>Level data is read in the <strong>GamePlayScreen</strong> once the selected menu button passes the name and level identifiers. The <strong>LoadLevelXml</strong> method is called as the screen begins to load, preparing all assets for the start of the game session:</p><p><pre class="brush: cpp">
void GamePlayScreen::LoadLevelXML()
{
    Coding4Fun::FallFury::XMLReader::Reader^ reader = ref new Coding4Fun::FallFury::XMLReader::Reader();
    
    Platform::String^ LevelName = Manager-&gt;Levels.Lookup(StaticDataHelper::CurrentLevelID);
    
    Windows::Foundation::IAsyncOperation&lt;Platform::Object^&gt;^ result = 
            reader-&gt;ReadXmlAsync(LevelName, Coding4Fun::FallFury::XMLReader::Models::XmlType::LEVEL);
    
        result-&gt;Completed =
            ref new AsyncOperationCompletedHandler&lt;Platform::Object^&gt;(this, &amp;GamePlayScreen::OnLevelLoadCompleted);
}
</pre></p><p>The selected ID passes from the menu screen to the game screen through <strong>CurrentLevelID</strong>, an intermediary value preserved in a <strong>StaticDataHelper</strong> class. The level file name is looked up based on the ID and then passed to <strong>ReadXmlAsync</strong> with the <strong>XmlType</strong> set to <strong>LEVEL</strong>. When the load completes, <strong>OnLevelLoadCompleted</strong> is invoked, and an additional helper class—<strong> LevelDataLoader</strong>—sets up the game components based on the received data:</p><p><pre class="brush: cpp">
void GamePlayScreen::OnLevelLoadCompleted(IAsyncOperation&lt;Platform::Object^&gt; ^op, AsyncStatus s)
{
        if (s == AsyncStatus::Completed)
        {
                InitializeSpriteBatch();    
        m_loader = ref new BasicLoader(Manager-&gt;m_d3dDevice.Get(), Manager-&gt;m_wicFactory.Get());
        CreateBear();
        
                LevelDataLoader^ loader = ref new LevelDataLoader((Coding4Fun::FallFury::XMLReader::Models::Level^)op-&gt;GetResults(), this);
        loader-&gt;SetupBear(GameBear);
        loader-&gt;SetupObstacles(m_obstacles);
        loader-&gt;SetupMonsters(m_monsters);
        loader-&gt;SetupButtons(m_buttons, m_buttonPrice);
        loader-&gt;SetupPowerups(m_powerups);
        m_currentLevelType = (LevelType) loader-&gt;CurrentLevel-&gt;LevelMeta-&gt;LevelType;
        
        StaticDataHelper::CurrentLevel = loader-&gt;CurrentLevel;
        StaticDataHelper::ButtonsTotal = loader-&gt;CurrentLevel-&gt;Buttons-&gt;Length;
        
        LoadTextures();
        
                CreateMonster();
                CreatePowerups();
        
        IsLevelLoaded = true;
        
        GameBear-&gt;TurnRight();
        m_particleSystem.CreatePreCachedParticleSets();
        LoadSounds();
        }
}
</pre></p><p>Each object is separated in its own method, such as <strong>SetupBear</strong> or <strong>SetupObstacles</strong>. <strong>SetupBear</strong>, for example, transforms the exposed managed <strong>Bear</strong> model to a native C&#43;&#43; <strong>Characters::Bear</strong> one:</p><p><pre class="brush: cpp">
void LevelDataLoader::SetupBear(Bear ^gameBear)
{
        gameBear-&gt;Position = float2(GetXPosition(CurrentLevel-&gt;GameBear-&gt;StartPosition), 0);    
    gameBear-&gt;MaxHealth = CurrentLevel-&gt;GameBear-&gt;MaxHealth;
    gameBear-&gt;CurrentHealth = CurrentLevel-&gt;GameBear-&gt;MaxHealth;
    gameBear-&gt;CurrentDamage = CurrentLevel-&gt;GameBear-&gt;Damage;
    gameBear-&gt;Velocity.y = CurrentLevel-&gt;GameBear-&gt;Velocity;
    gameBear-&gt;MaxCriticalDamage = CurrentLevel-&gt;GameBear-&gt;CriticalDamage;
    gameBear-&gt;Rotation = 0.0f;
}
</pre></p><h4>Conclusion</h4><p>Mixing C# and C&#43;&#43; components is not a complicated process. Nonetheless, it comes with specific restrictions and considerations, such as the format of the publicly exposed asynchronous calls. The above C#-based level loading engine highlights the fact that WinRT interoperability allows you to leverage the languages you know best in order to efficiently accomplish project tasks.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3090c59845c94007a593a14a0135ba1f">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements</comments>
      <itunes:summary>Rendering Level ElementsIn the previous article, you learned how to build level XML files in order to create playable levels. This article discusses how the internal parser works and how XML nodes become items on the game screen.&amp;nbsp; Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-6-Rendering-Level-Elements.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Project Interop – The C# ParserThanks to classes such as XmlSerializer and XDocument, parsing XML in .NET Framework is not a complicated task. Similarly, in the WinRT world there are alternatives such as Windows::Data::Xml::Dom. That being said, using the parser skeleton in C# this project leverages the existing codebase, adapting it to the specific level reading needs. Start by creating a new WinRT project that is the part of the existing solution. Make sure that you create a Windows Runtime Component:  There are major differences between the .NET and WinRT stacks, especially when it comes to building code that can be invoked from any potential WinRT project type, as is the case here. Make sure that the output of the newly created project is a Windows Runtime Component (WinMD file):  The XMLReader project reads much more than the level data—it also manages internal XML metadata such as user scores. This article, however, focuses only on level-related aspects of the engine. Reader is the one core class used here. It contains the ReadXml method, which receives the file name and the type of the XML file to be read. Regardless of the name, the XML file type determines the parsing rules, the root lookup location, and the produced output. The tier (level set) and individual level data are stored internally in the application folder, and the score metadata is outside the sandbox in the application data folder: 
async Task&amp;lt;Object&amp;gt; ReadXml(string fileName, XmlType type)
{
        StorageFile file = null;
   </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements</link>
      <pubDate>Wed, 23 Jan 2013 23:57:17 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/7ae7/6a8080f8-5fdb-4614-9540-da3c77cc7ae7/FallFuryPart6_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-6-Rendering-Level-Elements/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 5 - Creating Levels</title>
      <description><![CDATA[<h4>Creating Levels</h4><p>One of the goals set when developing FallFury was making the game extensible in regards to playable levels. Furthermore, I thought that it would make sense from the development and testing perspective to have levels as a completely separate entity that can be modified as necessary. For example, when a new power-up was introduced, I wanted to add an extra line in a level file and test it out. This was ultimately achieved by creating an XML-based level engine and in this article I will describe the level structure and design process.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels">http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels.</a>&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>The First Steps</h4><p>When I started working on the level engine concept, I began designing the potential XML file structure for the level and ended up with the following requirements:</p><ul><li><strong>Level Type Identifier</strong> – As different levels have different backgrounds and sound themes, there should be a way to mark a level type. There are currently four level types: dream, nightmare, space, and magic bean. </li><li><strong>The Starting Character Descriptor</strong> – When the game starts, the teddy bear has some initial, basic properties, such as maximum health level, horizontal position, and velocity. </li><li><strong>A Collection of Obstacles </strong>– For each level, obstacles are positioned differently, and it’s important to specify that. For some obstacles it might be desirable to disable the damage infliction component, while for others it might be good to maximize the damage caused by colliding with them. Also, there are multiple textures associated with different obstacle types, so I wanted to specify the obstacles to render regardless of the selected level type. </li><li><strong>A Collection of Monsters </strong>– Obstacles are not the only component that can damage the bear during gameplay. There are also monsters that can pop up and shoot at the main character. Similar to the bear, monsters represent a living entity and have some specific properties, such as the initial health, damage, starting position, velocity, and type. </li><li><strong>Buttons – </strong>These are the bonus point boosters in FallFury. The player collects as many of those as possible, and each of them should be individually positioned to form either a trail or a shape. </li><li><strong>Power-Ups</strong> – With the basic set of abilities, the bear is able to get some bonuses such as a cape that will speed-up his descent or a bubble that will protect him from incoming shells. </li></ul><p>The first build of the level engine integrated into FallFuryused percentage-based relative values to position elements on the screen. Although this seemed like a good idea at the time, it became problematic because</p><ul><li>It required the level to be a fixed size, which restricted element addition and level extension. </li><li>It caused problems with obstacles that needed to be scaled and therefore had a non-standard size. </li><li>Small modifications were harder to make because minimal adjustments would throw off the relative position. </li></ul><p>So, I switched to a pixel-based conditioning in which each position is relative to zero. With this in place, levels can be infinitely long (within the context of the machine’s rendering and memory capabilities)and extra elements can be more seamlessly added.</p><p>Additionally, levels need to be packaged together in individual sets, normally grouped by themes, without restriction. This is achieved with the help of an extra XML file,called <strong>core.xml</strong>, which keeps track of level tiers, and acts as a container that allows the developer to name and easily enable or disable specific levels .</p><p>The structure for the <strong>core.xml</strong> file looks like this:</p><p><pre class="brush: xml">
&lt;tiers&gt;
  &lt;tier name=&quot;GO, GO, TEDDY&quot;&gt;
    &lt;level name=&quot;mind travels&quot; file=&quot;GoGoTeddy\mind.xml&quot;&gt;&lt;/level&gt;
    &lt;level name=&quot;falling in&quot; file=&quot;Nightmare\full_pilot.xml&quot;&gt;&lt;/level&gt;
    &lt;level name=&quot;frontlines&quot; file=&quot;Nightmare\the_beginning.xml&quot;&gt;&lt;/level&gt;
    &lt;level name=&quot;the chase&quot; file=&quot;Nightmare\chasing_monsters.xml&quot;&gt;&lt;/level&gt;
  &lt;/tier&gt;
  &lt;tier name=&quot;SECRET GARDEN&quot;&gt;
    &lt;level name=&quot;bean stalking&quot; file=&quot;Garden\bean_stalking.xml&quot;/&gt;
    &lt;level name=&quot;thorn apart&quot; file=&quot;Garden\thorn_apart.xml&quot;/&gt;
  &lt;/tier&gt;
  &lt;!--&lt;tier name=&quot;Obstacle ***TEST***&quot;&gt;
    &lt;level name=&quot;Nightmare 0&quot; file=&quot;test\Obstacle\nightmare\0.xml&quot; /&gt;
    &lt;level name=&quot;Nightmare 1&quot; file=&quot;test\Obstacle\nightmare\1.xml&quot; /&gt;
    &lt;level name=&quot;Bean 0&quot; file=&quot;test\Obstacle\bean\0.xml&quot; /&gt;
    &lt;level name=&quot;Bean 1&quot; file=&quot;test\Obstacle\bean\1.xml&quot; /&gt;
    &lt;level name=&quot;Dream 0&quot; file=&quot;test\Obstacle\dream\0.xml&quot; /&gt;
    &lt;level name=&quot;Dream 1&quot; file=&quot;test\Obstacle\dream\1.xml&quot; /&gt;
  &lt;/tier&gt;--&gt;
  &lt;!--&lt;tier name=&quot;Death ***TEST***&quot;&gt;
    &lt;level name=&quot;Monster 0&quot; file=&quot;test\death\0.xml&quot; /&gt;
  &lt;/tier&gt;--&gt;
  &lt;!--&lt;tier name=&quot;Monster ***TEST***&quot;&gt;
    &lt;level name=&quot;0&quot; file=&quot;test\Monsters\0.xml&quot; /&gt;
    &lt;level name=&quot;1&quot; file=&quot;test\Monsters\1.xml&quot; /&gt;
    &lt;level name=&quot;2&quot; file=&quot;test\Monsters\2.xml&quot; /&gt;
    &lt;level name=&quot;3&quot; file=&quot;test\Monsters\3.xml&quot; /&gt;
    &lt;level name=&quot;4&quot; file=&quot;test\Monsters\4.xml&quot; /&gt;
    &lt;level name=&quot;5&quot; file=&quot;test\Monsters\5.xml&quot; /&gt;
    &lt;level name=&quot;6&quot; file=&quot;test\Monsters\6.xml&quot; /&gt;
    &lt;level name=&quot;7&quot; file=&quot;test\Monsters\7.xml&quot; /&gt;
    &lt;level name=&quot;8&quot; file=&quot;test\Monsters\8.xml&quot; /&gt;
    &lt;level name=&quot;9&quot; file=&quot;test\Monsters\9.xml&quot; /&gt;
    &lt;level name=&quot;10&quot; file=&quot;test\Monsters\10.xml&quot; /&gt;
  &lt;/tier&gt;--&gt;
  &lt;!--&lt;tier name=&quot;MEDALS *****TEST******&quot;&gt;
    &lt;level name=&quot;gold&quot; file=&quot;test\Medals\gold.xml&quot;&gt;&lt;/level&gt;
    &lt;level name=&quot;silver&quot; file=&quot;test\Medals\silver.xml&quot;&gt;&lt;/level&gt;
    &lt;level name=&quot;bronze&quot; file=&quot;test\Medals\bronze.xml&quot;&gt;&lt;/level&gt;
  &lt;/tier&gt;
  &lt;tier name=&quot;Buttons ***TEST***&quot;&gt;
    &lt;level name=&quot;1&quot; file=&quot;test\Buttons\single.xml&quot; /&gt;
    &lt;level name=&quot;Lots&quot; file=&quot;test\Buttons\multiple.xml&quot; /&gt;
  &lt;/tier&gt;
  &lt;tier name=&quot;Obstacles ***TEST***&quot;&gt;
    &lt;level name=&quot;Cape&quot; file=&quot;test\PowerUps\0.xml&quot; /&gt;
  &lt;/tier&gt;--&gt;
&lt;/tiers&gt;
</pre></p><p>Tiers that are commented out are ignored and the included levels aren’t on the game list. Also, the paths indicated for each <strong>file</strong> attribute—for each individual tier—are relative to the game folder itself. There is no limit on the number of subfolders that can be included in the path. The above structure will render this level set:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-6.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-7.jpg" alt="clip_image002" width="640" height="360" border="0"></a></p><h4>The Level XML</h4><p>Let’s now take a look at the layout of the level descriptor XML file:</p><p><pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;level type=&quot;0&quot;&gt;
  &lt;meta score=&quot;0&quot; buttonPrice=&quot;10&quot;&gt;&lt;/meta&gt;
  &lt;bear maxHealth=&quot;100&quot; startPosition=&quot;300&quot; velocity=&quot;8.0&quot; damage=&quot;11&quot; criticalDamage=&quot;20&quot; defaultAmmo=&quot;100&quot; /&gt;
  &lt;obstacles&gt;
    &lt;obstacle type=&quot;1&quot; x=&quot;119&quot; y=&quot;2300&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;3.14&quot; scale=&quot;1&quot; /&gt;
    &lt;obstacle type=&quot;3&quot; x=&quot;534.5&quot; y=&quot;3000&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;0&quot; scale=&quot;1&quot; /&gt;
    &lt;obstacle type=&quot;3&quot; x=&quot;534.5&quot; y=&quot;3300&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;0&quot; scale=&quot;1&quot; /&gt;
    &lt;obstacle type=&quot;1&quot; x=&quot;119&quot; y=&quot;4200&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;3.14&quot; scale=&quot;1&quot; /&gt;
    &lt;obstacle type=&quot;2&quot; x=&quot;546&quot; y=&quot;5000&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;0&quot; scale=&quot;1&quot; /&gt;
    &lt;obstacle type=&quot;1&quot; x=&quot;119&quot; y=&quot;5800&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;3.14&quot; scale=&quot;1&quot; /&gt;
    &lt;obstacle type=&quot;2&quot; x=&quot;546&quot; y=&quot;6600&quot; inflictsDamage=&quot;true&quot; healthDamage=&quot;5&quot; rotation=&quot;0&quot; scale=&quot;1&quot; /&gt;
  &lt;/obstacles&gt;
  &lt;monsters&gt;
    &lt;monster lifetime=&quot;3000&quot; scale=&quot;.2&quot; velocityX=&quot;2&quot; velocityY=&quot;2&quot; type=&quot;0&quot; x=&quot;460&quot; y=&quot;19900&quot; maxHealth=&quot;80&quot; bonus=&quot;100&quot; lives=&quot;0&quot; damage=&quot;10&quot; criticalDamage=&quot;8&quot; defaultAmmo=&quot;50&quot; /&gt;
    &lt;monster lifetime=&quot;3000&quot; scale=&quot;.2&quot; velocityX=&quot;2&quot; velocityY=&quot;2&quot; type=&quot;1&quot; x=&quot;460&quot; y=&quot;25000&quot; maxHealth=&quot;80&quot; bonus=&quot;100&quot; lives=&quot;0&quot; damage=&quot;10&quot; criticalDamage=&quot;8&quot; defaultAmmo=&quot;50&quot; /&gt;
    &lt;monster lifetime=&quot;3000&quot; scale=&quot;.2&quot; velocityX=&quot;2&quot; velocityY=&quot;2&quot; type=&quot;2&quot; x=&quot;460&quot; y=&quot;34500&quot; maxHealth=&quot;80&quot; bonus=&quot;100&quot; lives=&quot;0&quot; damage=&quot;10&quot; criticalDamage=&quot;8&quot; defaultAmmo=&quot;50&quot; /&gt;
    &lt;monster lifetime=&quot;6000&quot; scale=&quot;.4&quot; velocityX=&quot;2&quot; velocityY=&quot;2&quot; type=&quot;3&quot; x=&quot;460&quot; y=&quot;41400&quot; maxHealth=&quot;180&quot; bonus=&quot;100&quot; lives=&quot;0&quot; damage=&quot;17&quot; criticalDamage=&quot;8&quot; defaultAmmo=&quot;50&quot; /&gt;
  &lt;/monsters&gt;
  &lt;buttons&gt;
    &lt;button x=&quot;300&quot; y=&quot;800&quot; /&gt;
    &lt;button x=&quot;360&quot; y=&quot;800&quot; /&gt;
    &lt;button x=&quot;300&quot; y=&quot;860&quot; /&gt;
    &lt;button x=&quot;360&quot; y=&quot;860&quot; /&gt;
    &lt;button x=&quot;300&quot; y=&quot;920&quot; /&gt;
    &lt;button x=&quot;360&quot; y=&quot;920&quot; /&gt;
    &lt;button x=&quot;300&quot; y=&quot;980&quot; /&gt;
    &lt;button x=&quot;360&quot; y=&quot;980&quot; /&gt;
  &lt;/buttons&gt;
  &lt;powerups&gt;
    &lt;powerup category=&quot;1&quot; type=&quot;4&quot; x=&quot;140&quot; y=&quot;9200&quot; effect=&quot;3&quot; lifespan=&quot;4&quot;&gt;&lt;/powerup&gt;
    &lt;powerup category=&quot;1&quot; type=&quot;3&quot; x=&quot;480&quot; y=&quot;19800&quot; effect=&quot;10&quot; lifespan=&quot;6&quot;&gt;&lt;/powerup&gt;
    &lt;powerup category=&quot;1&quot; type=&quot;0&quot; x=&quot;480&quot; y=&quot;27500&quot; effect=&quot;10&quot; lifespan=&quot;6&quot;&gt;&lt;/powerup&gt;
    &lt;powerup category=&quot;1&quot; type=&quot;1&quot; x=&quot;100&quot; y=&quot;34000&quot; effect=&quot;10&quot; lifespan=&quot;6&quot;&gt;&lt;/powerup&gt;
    &lt;powerup category=&quot;1&quot; type=&quot;0&quot; x=&quot;100&quot; y=&quot;41200&quot; effect=&quot;10&quot; lifespan=&quot;6&quot;&gt;&lt;/powerup&gt;
  &lt;/powerups&gt;
&lt;/level&gt;
</pre></p><p>The opening <strong>level</strong> tag carries a type attribute. This is level theme flag. It can be set to one of the three four values:</p><ul><li><strong>0</strong> – The Nightmare Theme </li><li><strong>1</strong> – The Magic Bean Theme </li><li><strong>2</strong> – The Dream Theme </li><li><strong>3</strong> – The Space Theme </li></ul><p>You can see the design differences in the images below:</p><table border="0" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top" width="360"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-4.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-5.jpg" alt="clip_image004" width="270" height="270" border="0"></a></p></td><td valign="top" width="360"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D-2.jpg"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb-3.jpg" alt="clip_image006" width="269" height="270" border="0"></a></p></td></tr><tr><td valign="top" width="360"><p>Nightmare</p></td><td valign="top" width="360"><p>Magic Bean</p></td></tr><tr><td valign="top" width="719">&nbsp;</td></tr><tr><td valign="top" width="360"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B3%5D-3.jpg"><img title="clip_image008" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008_thumb-4.jpg" alt="clip_image008" width="269" height="270" border="0"></a></p></td><td valign="top" width="360"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B3%5D-1.jpg"><img title="clip_image010" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010_thumb-2.jpg" alt="clip_image010" width="269" height="270" border="0"></a></p></td></tr><tr><td valign="top" width="360"><p>Dream</p></td><td valign="top" width="360"><p>Space</p></td></tr></tbody></table><p>Remember, that obstacles and the level theme itself do not influence much other than the background and soundboard.</p><p>Once the type is specified, the <strong>meta</strong> tag brings up the <strong>score</strong> and <strong>buttonPrice</strong> attributes. If you for some reason want to create a level including an initial score, you can specify it here. And because buttons are fixed bonus assets that are all created equal, each of them carries a given bonus point weight. The score based on the collected buttons is calculated at the end of the game and relies on the value specified in the <strong>meta</strong> tag.</p><h4>Obstacles</h4><p>Next comes the obstacle collection, which is represented by the <strong>obstacles</strong> tag. This tag is required even if there are no obstacles on a given level. Simply use <strong>&lt;obstacles /&gt;</strong> as necessary. Each child node represents an instance of an obstacle that can be choosen from the following enum:</p><p><pre class="brush: cpp">
enum class ObstacleType
{
    OT_CLOUD = 0,
    OT_SPIKE_NIGHTMARE_LARGE = 1,
    OT_SPIKE_NIGHTMARE_MEDIUM = 2,
    OT_SPIKE_NIGHTMARE_SMALL = 3,
    OT_BEAN_A = 4,
    OT_BEAN_B = 5,
    OT_BEAN_C = 6,
    OT_BEAN_D = 7,
    OT_BEAN_E = 8,
    OT_SPACE_ROCKET = 9,
    OT_SPACE_COMET_A = 10,
    OT_SPACE_COMET_B = 11,
    OT_SPACE_SATELLITE = 12,
    OT_SPACE_UFO = 13,
    OT_SPACE_BALL = 14
};
</pre></p><p>Here is the complete table showing the appearance of each of them:</p><table border="0" cellspacing="0" cellpadding="0"><tbody><tr><td width="246"><p>OT_CLOUD</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B3%5D-3.jpg"><img title="clip_image012" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012_thumb-3.jpg" alt="clip_image012" width="285" height="103" border="0"></a></p></td></tr><tr><td valign="top" width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPIKE_NIGHTMARE_LARGE</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B3%5D-3.jpg"><img title="clip_image014" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014_thumb-3.jpg" alt="clip_image014" width="126" height="116" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPIKE_NIGHTMARE_MEDIUM</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016%5B3%5D-2.jpg"><img title="clip_image016" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016_thumb-3.jpg" alt="clip_image016" width="234" height="131" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPIKE_NIGHTMARE_SMALL</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image018%5B3%5D-2.jpg"><img title="clip_image018" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image018_thumb-2.jpg" alt="clip_image018" width="245" height="126" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_BEAN_A</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image020%5B3%5D-1.jpg"><img title="clip_image020" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image020_thumb-1.jpg" alt="clip_image020" width="281" height="174" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_BEAN_B</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image022%5B3%5D-1.jpg"><img title="clip_image022" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image022_thumb-1.jpg" alt="clip_image022" width="133" height="165" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_BEAN_C</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image024%5B3%5D-1.jpg"><img title="clip_image024" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image024_thumb-1.jpg" alt="clip_image024" width="179" height="152" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_BEAN_D</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image026%5B3%5D-1.jpg"><img title="clip_image026" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image026_thumb-1.jpg" alt="clip_image026" width="197" height="198" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_BEAN_E</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image028%5B3%5D-1.jpg"><img title="clip_image028" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image028_thumb-1.jpg" alt="clip_image028" width="217" height="181" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPACE_ROCKET</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image030%5B3%5D-1.jpg"><img title="clip_image030" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image030_thumb-1.jpg" alt="clip_image030" width="165" height="181" border="0"></a></p></td></tr><tr><td valign="top" width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPACE_COMET_A</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image032%5B3%5D-1.jpg"><img title="clip_image032" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image032_thumb-1.jpg" alt="clip_image032" width="186" height="186" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPACE_COMET_B</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image034%5B3%5D.jpg"><img title="clip_image034" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image034_thumb.jpg" alt="clip_image034" width="131" height="132" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPACE_SATELLITE</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image036%5B3%5D.jpg"><img title="clip_image036" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image036_thumb.jpg" alt="clip_image036" width="150" height="197" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPACE_UFO</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image038%5B3%5D.jpg"><img title="clip_image038" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image038_thumb.jpg" alt="clip_image038" width="202" height="187" border="0"></a></p></td></tr><tr><td width="246">&nbsp;</td><td valign="top" width="474">&nbsp;</td></tr><tr><td width="246"><p>OT_SPACE_BALL</p></td><td valign="top" width="474"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image040%5B3%5D.jpg"><img title="clip_image040" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image040_thumb.jpg" alt="clip_image040" width="179" height="189" border="0"></a></p></td></tr></tbody></table><p>No matter how the obstacles are positioned, they will either be located in the visible area or displaced outside the viewport and not displayed. The ultimate position is taken from the obstacle size and is relative to the center of the texture. For example, if an obstacle texture is 400- pixels wide, the X-relative position should be set to 200. If the position differs from the starting one, however, the obstacle texture is cut to include the area that fits in the 768 pixel wide playable zone visible. There are no restrictions regarding the Y position.</p><p>To help in level creation, some obstacles have pre-defined left and right margins. For example:</p><ul><li><strong>OT_BEAN_A:</strong> 269.5 (Left), 498.5 (right, with 3.14 rotation) </li><li><strong>OT_BEAN_B:</strong> 128.5 (left), 638.5 (right, with 3.14 rotation) </li><li><strong>OT_BEAN_C:</strong> 172 (left), 596 (right, with 3.14 rotation) </li><li><strong>OT_BEAN_D:</strong> 188.5 (left), 579.5 (right, with 3.14 rotation) </li><li><strong>OT_BEAN_E:</strong> 206.5 (left), 561.5 (right, with 3.14 rotation) </li></ul><p>The <strong>inflictsDamage</strong> attribute determines whether the obstacle harms the main character. If it is set to <strong>false</strong>, the character will still make the sound of colliding with it but will not lose any health points. The primary use for this attribute is level testing.If it is set to <strong>true</strong>, the character will loose the amount of health points indicated by the <strong>healthDamage</strong> attribute.</p><p>The <strong>rotation</strong> and <strong>scale</strong> attributes can be used to flip and resize the texture as needed. Rotation is measured in radians, and the scale is a normalized value in which 1.0 represents 100% of the scale.</p><h4>Monsters</h4><p>As with obstacles, the <strong>monsters</strong> node should never be omitted from the file and should at least contain a placeholder: <strong>&lt;monsters /&gt;</strong>. Unlike obstacles, however, monsters are dynamic and do not have fixed positions. Moreover, monsters have limited active time during gameplay. The first attribute,<strong>lifetime</strong>, determines the length of the fall during which the monster will be visible in the viewport. With the <strong>y</strong> attribute as the Y-based position at which the monster appears, at the <strong>y&#43;lifetime</strong> position the monster simply flies away if not killed.</p><p>The <strong>scale</strong> attribute carries the same purpose as the one for the obstacle—normalized texture size relative to the size of the original image file. As such, the level designer does not have to worry about linking the width and height of the monster when resizing and can instead use a percentage-like value to scale the monster up or down, simultaneously modifying both the width and the height with zero stretching.</p><p>Nextup are <strong>velocityX</strong> and <strong>velocityY</strong>. These two attributes are used to set the motion velocity when the monster is already visible. Instead of being a static shooting entity, the enemy moves on a randomized zig-zag path at the bottom of the screen. The horizontal and vertical displacement—in pixels, per update cycle—is individually set through the values carried by the above-mentioned attributes. If necessary, this functionality can be disabled in the code-behind by assigning a fixed value for the vertical and horizontal movement for all monsters that are being loaded on a given level.</p><p>The monster type is an <strong>integer</strong> value that is translated in a value from the following enum (located in <strong>MonsterType.h</strong>):</p><p><pre class="brush: cpp">
enum class MonsterType
{
    MT_NIGHTMARE_A = 0,
    MT_NIGHTMARE_B = 1,
    MT_NIGHTMARE_C = 2,
    MT_MAGICBEAN_A = 3,
    MT_MAGICBEAN_B = 4,
    MT_MAGICBEAN_C = 5,
    MT_CANDYLAND_A = 6,
    MT_CANDYLAND_B = 7,
    MT_CANDYLAND_C = 8,
    MT_CANDYLAND_D = 9,
    MT_CANDYLAND_E = 10
};
</pre></p><p>Here is a table that shows the texture associated with each identifier:</p><table border="0" cellspacing="0" cellpadding="0"><tbody><tr><td width="162"><p>MT_NIGHTMARE_A</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image042%5B3%5D.jpg"><img title="clip_image042" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image042_thumb.jpg" alt="clip_image042" width="132" height="130" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_NIGHTMARE_B</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image044%5B3%5D.jpg"><img title="clip_image044" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image044_thumb.jpg" alt="clip_image044" width="111" height="140" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_NIGHTMARE_C</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image046%5B3%5D.jpg"><img title="clip_image046" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image046_thumb.jpg" alt="clip_image046" width="79" height="139" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_MAGICBEAN_A</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image048%5B3%5D.jpg"><img title="clip_image048" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image048_thumb.jpg" alt="clip_image048" width="200" height="136" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_MAGICBEAN_B</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image050%5B3%5D.jpg"><img title="clip_image050" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image050_thumb.jpg" alt="clip_image050" width="74" height="139" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_MAGICBEAN_C</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image052%5B3%5D.jpg"><img title="clip_image052" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image052_thumb.jpg" alt="clip_image052" width="123" height="140" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_CANDYLAND_A</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image054%5B3%5D.jpg"><img title="clip_image054" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image054_thumb.jpg" alt="clip_image054" width="94" height="106" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_CANDYLAND_B</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image056%5B3%5D.jpg"><img title="clip_image056" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image056_thumb.jpg" alt="clip_image056" width="64" height="117" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_CANDYLAND_C</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image058%5B3%5D.jpg"><img title="clip_image058" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image058_thumb.jpg" alt="clip_image058" width="121" height="140" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_CANDYLAND_D</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image060%5B3%5D.jpg"><img title="clip_image060" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image060_thumb.jpg" alt="clip_image060" width="187" height="138" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr><tr><td width="162"><p>MT_CANDYLAND_E</p></td><td valign="top" width="216"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image062%5B3%5D.jpg"><img title="clip_image062" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image062_thumb.jpg" alt="clip_image062" width="123" height="139" border="0"></a></p></td></tr><tr><td width="162">&nbsp;</td><td valign="top" width="216">&nbsp;</td></tr></tbody></table><p>Each monster has three separate textures associated with it. The three textures are cycled inside the update loop for each monster entity when the monster becomes visible, creating the movement effect:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image063%5B3%5D.png"><img title="clip_image063" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image063_thumb.png" alt="clip_image063" width="444" height="155" border="0"></a></p><p>Each monster currently shoots only one type of ammo: a red plasma ball. Be aware, however, that there is a preprogrammed condition in which the last monster in the XML file collection is automatically considered the final boss. This means the <strong>scale</strong>, <strong>maxHealth</strong> and <strong>lifetime</strong> properties must be manually adjusted to reflect the effect. Without doing so, the last monster will, regardless of the XML setting, switch in-game to a triple fireball shot that inflicts three times the damage indicated by the <strong>damage</strong> attribute:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image065%5B3%5D.jpg"><img title="clip_image065" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image065_thumb.jpg" alt="clip_image065" width="345" height="279" border="0"></a></p><p>Each monster can have limited ammo as set by the <strong>defaultAmmo</strong> attribute. In the case that the ammo is exhausted before the monster expires, the monster will continue its motion at the bottom of the screen without inflicting direct damage to the main character.</p><h4>Buttons</h4><p>These are the least complex entities and only carry an X and a Y position. Given those coordinates, relative to the left margin of the visible area, a button texture is rendered:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image067%5B3%5D.jpg"><img title="clip_image067" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image067_thumb.jpg" alt="clip_image067" width="408" height="258" border="0"></a></p><p>Once picked-up, the button counter is increased by one and the meta-score incremented by the value set in the <strong>meta</strong> tag at the beginning of the level XML as long as the feature is activated in the code-behind.</p><h4>Power-ups</h4><p>To make the game more fun, there are bonus elements that can be picked up by the bear in order to enhance its performance or protection. These elements are declared in the <strong>&lt;powerups/&gt;</strong> collection. First and foremost, it is important to declare whether the power-up is positive or negative. In the current version of FallFury, only positive power-ups are included. Nonetheless, the harness for negative ones is already integrated in the parser. Therefore, the <strong>category</strong> attribute should be set to 1 if the power-up has a positive effect and 0 for a negative effect. This value will only have an effect over the sound played when the bonus is collected.</p><p>The power-up type can be one of the following (enum located in <strong>PoweupType.h</strong>):</p><p><pre class="brush: cpp">
enum class PowerupType
{
    HEALTH = 0,
    HELMET = 1,
    PARACHUTE = 2,
    BUBBLE = 3,
    CAPE = 4,
    AXE = 5,
    BOOMERANG = 6,
    HAMMER = 7,
    KNIFE = 8,
    PLASMA_BALL = 9,
    CIRCLE = 10
};
</pre></p><p>&nbsp;</p><p>The table below shows the power-up texture appearance. Behaviors are already defined in the game and influenced by only the <strong>effect</strong> and <strong>lifespan</strong> (seconds) attributes:</p><table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td width="120"><p>HEALTH</p></td><td width="360"><p>Restores the character health, incremented by the value in <strong>effect</strong>. The <strong>lifespan</strong> attribute is ignored.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image069%5B3%5D.jpg"><img title="clip_image069" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image069_thumb.jpg" alt="clip_image069" width="52" height="52" border="0"></a></p></td></tr><tr><td width="120"><p>HELMET</p></td><td width="360"><p>Adds a helmet to the bear, setting the maximum health to the <strong>effect</strong> value. Active for the duration of <strong>lifespan</strong>.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image071%5B3%5D.jpg"><img title="clip_image071" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image071_thumb.jpg" alt="clip_image071" width="51" height="53" border="0"></a></p></td></tr><tr><td width="120"><p>PARACHUTE</p></td><td width="360"><p>Slows down the fall of the bear, setting the descent velocity to the <strong>effect</strong> value. Active for the duration of <strong>lifespan</strong>.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image073%5B3%5D.jpg"><img title="clip_image073" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image073_thumb.jpg" alt="clip_image073" width="52" height="52" border="0"></a></p></td></tr><tr><td width="120"><p>BUBBLE</p></td><td width="360"><p>Wraps the character in a protective bubble, setting the maximum health to the value of the <strong>effect</strong> attribute. Active for the duration of <strong>lifespan</strong>.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image075%5B3%5D.jpg"><img title="clip_image075" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image075_thumb.jpg" alt="clip_image075" width="52" height="50" border="0"></a></p></td></tr><tr><td width="120"><p>CAPE</p></td><td width="360"><p>Accelerates the descent by multiplying the velocity by the value of <strong>effect</strong>. Active for the duration of <strong>lifespan</strong>.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image077%5B3%5D.jpg"><img title="clip_image077" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image077_thumb.jpg" alt="clip_image077" width="52" height="52" border="0"></a></p></td></tr><tr><td width="120"><p>AXE</p></td><td width="360"><p>Sets the current character weapon to an axe. The damage is determined by the <strong>effect</strong> attribute and <strong>lifespan</strong> is ignored.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image079%5B3%5D.jpg"><img title="clip_image079" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image079_thumb.jpg" alt="clip_image079" width="52" height="54" border="0"></a></p></td></tr><tr><td width="120"><p>BOOMERANG</p></td><td width="360"><p>Sets the current character weapon to a boomerang. The damage is determined by the <strong>effect</strong> attribute and <strong>lifespan</strong> is ignored.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image081%5B3%5D.jpg"><img title="clip_image081" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image081_thumb.jpg" alt="clip_image081" width="51" height="52" border="0"></a></p></td></tr><tr><td width="120"><p>HAMMER</p></td><td width="360"><p>Sets the current character weapon to a hammer. The damage is determined by the <strong>effect</strong> attribute and <strong>lifespan</strong> is ignored.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image083%5B3%5D.jpg"><img title="clip_image083" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image083_thumb.jpg" alt="clip_image083" width="52" height="52" border="0"></a></p></td></tr><tr><td width="120"><p>KNIFE</p></td><td width="360"><p>Sets the current character weapon to a knife. The damage is determined by the <strong>effect</strong> attribute and <strong>lifespan</strong> is ignored.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image085%5B3%5D.jpg"><img title="clip_image085" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image085_thumb.jpg" alt="clip_image085" width="52" height="52" border="0"></a></p></td></tr><tr><td width="120"><p>PLASMA_BALL</p></td><td width="360"><p>Sets the current character weapon to a plasma ball. The damage is determined by the <strong>effect</strong> attribute and <strong>lifespan</strong> is ignored.</p></td><td valign="top" width="72"><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image087%5B3%5D.jpg"><img title="clip_image087" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image087_thumb.jpg" alt="clip_image087" width="54" height="52" border="0"></a></p></td></tr></tbody></table><p>CIRCLE is a helper power-up that has no effect on the bear and is instead used as an additional texture overlay along with any other power-up in order to create a pulsating circle effect.</p><h4>Conclusion</h4><p>FallFury ships with a dozen of sample levels that showcase all of the elements described in the article. At the moment, a level editor is in the works, but it isn’t too complicated to build XML files manually. To do so, you need to consider the pixel-based locations and ensure that they’re all in the visible area—the game engine will automatically handle all other displacements and adjustments.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3a3c8f6f0baa49dab538a14a01384bb7">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels</comments>
      <itunes:summary>Creating LevelsOne of the goals set when developing FallFury was making the game extensible in regards to playable levels. Furthermore, I thought that it would make sense from the development and testing perspective to have levels as a completely separate entity that can be modified as necessary. For example, when a new power-up was introduced, I wanted to add an extra line in a level file and test it out. This was ultimately achieved by creating an XML-based level engine and in this article I will describe the level structure and design process. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-5-Creating-Levels.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. The First StepsWhen I started working on the level engine concept, I began designing the potential XML file structure for the level and ended up with the following requirements: Level Type Identifier – As different levels have different backgrounds and sound themes, there should be a way to mark a level type. There are currently four level types: dream, nightmare, space, and magic bean. The Starting Character Descriptor – When the game starts, the teddy bear has some initial, basic properties, such as maximum health level, horizontal position, and velocity. A Collection of Obstacles – For each level, obstacles are positioned differently, and it’s important to specify that. For some obstacles it might be desirable to disable the damage infliction component, while for others it might be good to maximize the damage caused by colliding with them. Also, there are multiple textures associated with different obstacle types, so I wanted to specify the obstacles to render regardless of the selected level type. A Collection of Monsters – Obstacles are not the only component that can damage the bear during gameplay. There are also monsters that can pop up and shoot at the main character. Similar to the bear, monsters r</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels</link>
      <pubDate>Wed, 23 Jan 2013 23:57:11 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/b079/411aa110-67a6-4cda-9606-e3473f1bb079/FallFuryPart5_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-5-Creating-Levels/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 4 - XAML Interop</title>
      <description><![CDATA[<p>As mentioned earlier in the series, FallFury does not solely rely on DirectX to display content to the user. As a Windows Store game, FallFury leverages the new <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh825871.aspx">Direct2D (XAML) project template</a>, available in Visual Studio 2012.&nbsp; Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop">http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>The Concept of a Swap Chain</h4><p>Before I go into detail about the DirectX and XAML interop in FallFury, I want to cover one important aspect of DirectX development that you need to familiarize yourself with: the swap chain.</p><p>When your graphics adapter draws on the visual surface, you, as the user, see only minor potential redraws. Internally, however, the device switches buffers that reflect the displayed content, with each buffer representing a frame that has to be drawn. You can deduce from this that any swap chain has at least two buffers that it can switch between.</p><p>For example, if I want to display my character as being displaced by a specific amount of pixels, the buffer will at the outset present to me the character in its initial position, while the second buffer will be constructed in the background with the proper position adjustments. The first frame, made from the content from the first buffer, will be discarded, and then the second frame will be displayed, and so on. This process occurs at a very high speed that depends on the processing capabilities of the graphics adapter, so the user does not notice the swapping itself.</p><p>The most common swap chain is composed of two buffers—the screenbuffer and the secondary framebuffer.</p><h4>SwapChainBackgroundPanel</h4><p>DirectX interoperability with XAML simplifies a lot of routine tasks that would otherwise be handled with manual rendering procedures, such as a menu system or a simple game HUD. That being said, the way the XAML workflow is organized in a Direct2D project is <a href="http://msdn.microsoft.com/en-US/library/windows/apps/hh825871">quite different</a> compared to a standard XAML Windows Store or Windows Phone application.</p><p>The core difference is that there is no navigational system per-se and the fundamental entity in a Direct2D (XAML) project that manages the XAML content is a <a href="http://msdn.microsoft.com/library/windows/apps/Hh702626">SwapChainBackgroundPanel</a> control. This control allows the developer to overlay XAML elements on top of the DirectX renders. It replaces the normal page-based layout with one in which it is sole container for every XAML control that has to be used in the application. This necessitates that you will have to organize the secondary elements in such a way that the correct set is displayed for the current application state.</p><p>For example, if the user is in the main menu, menu options as well as the game logo should be shown. When the user switches to the game mode, the HUD should appear and the menu should become hidden. Although both the menu and the HUD are a part of the same SwapChainBackgroundPanel, I will have to manually manage state and visibility changes.</p><p>Using the SwapChainBackgroundPanel also means that you will have to enforce specific graphic configuration rules in your application. One of them applies to setting up the swap chain. When you set up the scaling, it must be set to <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh404526(v=vs.85).aspx">DXGI_SCALING_STRETCH</a>:</p><p><pre class="brush: cpp">
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Width = static_cast&lt;UINT&gt;(m_renderTargetSize.Width); 
swapChainDesc.Height = static_cast&lt;UINT&gt;(m_renderTargetSize.Height);
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.Stereo = false; 
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc.Flags = 0;
</pre></p><p>&nbsp;</p><p>The swap chain itself should be configured for composition, mixing the native DirectX buffer with the overlaid XAML. This is done by calling <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh404558(v=vs.85).aspx">CreateSwapChainForComposition</a>:</p><p><pre class="brush: cpp">
ThrowIfFailed(
    dxgiFactory-&gt;CreateSwapChainForComposition(
        m_d3dDevice.Get(),
        &amp;swapChainDesc,
        nullptr,
        &amp;m_swapChain
        )
    );

ComPtr&lt;ISwapChainBackgroundPanelNative&gt; panelNative;
ThrowIfFailed(
    reinterpret_cast&lt;IUnknown*&gt;(m_panel)-&gt;QueryInterface(IID_PPV_ARGS(&amp;panelNative))
    );

ThrowIfFailed(
    panelNative-&gt;SetSwapChain(m_swapChain.Get())
    );
</pre></p><p>There really isn’t much additional configuration work beyond this point. Remember, that the XAML content will <strong>always be overlaid on top of the DirectX content</strong>; therefore, plan the game components accordingly.</p><h4>The XAML Menu System</h4><p>The menu is at the core of the FallFury experience. When designing it, I was inspired by how Dance Central built the user interaction mechanism, and I tried to implement a similar approach in which the user would have to slide the button to the right instead of simply tapping on it:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-4.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-5.jpg" alt="clip_image002" width="624" height="317" border="0"></a></p><p>Each menu item is built around a custom <strong>MenuItem</strong> control (<strong>MenuItem.xaml</strong>):</p><p><pre class="brush: xml">
&lt;UserControl
    x:Class=&quot;Coding4Fun.FallFury.MenuItem&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:local=&quot;using:Coding4Fun.FallFury&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot;
    x:Name=&quot;menuItem&quot;
    Margin=&quot;10, 0, 0, 10&quot;&gt;

    &lt;Grid 
        Height=&quot;65&quot; 
        ManipulationMode=&quot;TranslateX&quot;
        ManipulationCompleted=&quot;Grid_ManipulationCompleted&quot;
        ManipulationDelta=&quot;Grid_ManipulationDelta&quot; 
        x:Name=&quot;ControlContainer&quot;
        PointerPressed=&quot;Grid_PointerPressed&quot; 
        PointerReleased=&quot;Grid_PointerReleased&quot;&gt;
        
        &lt;Grid.Resources&gt;
            &lt;Storyboard x:Name=&quot;ArrowAnimator&quot;&gt;
                &lt;DoubleAnimation Storyboard.TargetName=&quot;ImageTranslateTransform&quot;
                                 Storyboard.TargetProperty=&quot;X&quot;
                                 From=&quot;0&quot;
                                 To=&quot;20&quot;
                                 Duration=&quot;0:0:0.4&quot;
                                 RepeatBehavior=&quot;Forever&quot;
                                 AutoReverse=&quot;True&quot;&gt;
                &lt;/DoubleAnimation&gt;
            &lt;/Storyboard&gt;

        &lt;/Grid.Resources&gt;
        
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height=&quot;10&quot; /&gt;
            &lt;RowDefinition /&gt;
            &lt;RowDefinition /&gt;
            &lt;RowDefinition Height=&quot;10&quot; /&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;Grid.ColumnDefinitions&gt;
            &lt;ColumnDefinition Width=&quot;10&quot; /&gt;
            &lt;ColumnDefinition /&gt;
        &lt;/Grid.ColumnDefinitions&gt;
        &lt;StackPanel Orientation=&quot;Horizontal&quot; Grid.RowSpan=&quot;4&quot; Grid.ColumnSpan=&quot;4&quot;&gt;
            &lt;!-- width is sent in code behind, have to get this dynamic ...  --&gt;
            &lt;Grid Width=&quot;350&quot; x:Name=&quot;coverRectangle&quot;&gt;
                &lt;Rectangle Fill=&quot;#303030&quot; /&gt;
                &lt;Rectangle 
                    Fill=&quot;Red&quot; 
                    x:Name=&quot;coverActiveRectangle&quot; /&gt;
            &lt;/Grid&gt;
            &lt;Image x:Name=&quot;MenuImage&quot; Source=&quot;ms-appx:///MenuItems/single_arrow.png&quot; Margin=&quot;10,0,0,0&quot; Stretch=&quot;Uniform&quot;&gt;
                &lt;Image.RenderTransform&gt;
                    &lt;TranslateTransform x:Name=&quot;ImageTranslateTransform&quot;&gt;&lt;/TranslateTransform&gt;
                &lt;/Image.RenderTransform&gt;
            &lt;/Image&gt;
        &lt;/StackPanel&gt;
        &lt;!----&gt;

        &lt;TextBlock 
            Text=&quot;{Binding ElementName=menuItem, RelativeSource={RelativeSource Self}, Path=Label}&quot;
            Grid.RowSpan=&quot;4&quot;
            Grid.ColumnSpan=&quot;4&quot;
            Style=&quot;{StaticResource MenuItemText}&quot;&gt;

        &lt;/TextBlock&gt;
        
        &lt;MediaElement x:Name=&quot;coreMenuMedia&quot; Source=&quot;ms-appx:///Assets/Sounds/MenuTap.wav&quot; AutoPlay=&quot;False&quot;&gt;&lt;/MediaElement&gt;
        &lt;MediaElement x:Name=&quot;slideMenuMedia&quot; Source=&quot;ms-appx:///Assets/Sounds/MenuSlide.wav&quot; AutoPlay=&quot;False&quot;&gt;&lt;/MediaElement&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre></p><p>There is a core storyboard that is used to perform an image bounce. Initial tests showed that that most users tend to follow the standard “click-and-go” pattern and even though the implemented button was a slider, they tried to click it at least once, expecting the game to take them to the next screen. To avoid this, I introduced a visual arrow indicator that bounces left and right to indicate the direction of the necessary slide.</p><p>When the sliding occurs, the overlay grid width is being adjusted relative to the manipulation. At the same time, the button changes from passive state (dark background):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image003%5B3%5D.png"><img title="clip_image003" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image003_thumb.png" alt="clip_image003" width="423" height="75" border="0"></a></p><p>to active state (red background):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D.png"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb.png" alt="clip_image004" width="465" height="76" border="0"></a></p><p>Internally, the double-arrow image replaces the single-arrow one and is translated across the X-axis to create a bouncing effect:</p><p><pre class="brush: cpp">
void MenuItem::Grid_PointerPressed(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
    BitmapImage^ image = ref new BitmapImage(ref new Uri(&quot;ms-appx:///MenuItems/double_arrow.png&quot;));
    MenuImage-&gt;Source = image;
    
    coverActiveRectangle-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
    ((Storyboard^)ControlContainer-&gt;Resources-&gt;Lookup(&quot;ArrowAnimator&quot;))-&gt;Begin();
    
    coreMenuMedia-&gt;Play();
}
</pre></p><p>As the user drags the finger on the button, the red overlay size should be adjusted accordingly. The size adjustment can be easily tracked in the ManipulationDelta event handler for the focused grid:</p><p><pre class="brush: cpp">
void MenuItem::Grid_ManipulationDelta(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs^ e)
{
    double diff = e-&gt;Cumulative.Translation.X;
    
    if (diff &gt; maxDeltaSize)
    {
        diff = maxDeltaSize;
    }
    else if (diff &lt; 0)
    {
        diff = 0;
    }
    
    coverRectangle-&gt;Width = initialBarWidth &#43; diff;
}
</pre></p><p>When the user action on the button is completed, the ManipulationCompleted event handler is triggered on the same overlay grid. If the relative drag hits the critical threshold, the action linked to the button should be invoked:</p><p><pre class="brush: cpp">
void MenuItem::Grid_ManipulationCompleted(Platform::Object^ sender, Windows::UI::Xaml::Input::ManipulationCompletedRoutedEventArgs^ e)
{
    float diff = e-&gt;Cumulative.Translation.X;
    
    if (diff &gt; maxDeltaSize - 50) // slight buffer
    {
        slideMenuMedia-&gt;Play();
        OnButtonSelected(this, Label);
    }
    
    ResetElements();
}
</pre></p><p>There are also local sound effects that are played when the slider-button is tapped and moved to the end. Both are handled by separate <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.mediaelement">MediaElement</a> controls that avoid an internal sound file switch, calling instead the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.mediaelement.play">Play</a> method as necessary. The <strong>OnButtonSelected</strong> event handler can be dynamically hooked in the application backend.</p><p>Each button also has a visible content area that can display a text label. It can be set through a DependencyProperty:</p><p><pre class="brush: cpp">
DependencyProperty^ MenuItem::_LabelProperty = 
    DependencyProperty::Register(&quot;Label&quot;, 
    Platform::String::typeid,
    MenuItem::typeid, 
    nullptr);
</pre></p><p>In its current configuration, the menu label can be also set in XAML:</p><p><pre class="brush: xml">
&lt;local:MenuItem x:Name=&quot;btnNewGame&quot; Label=&quot;new game&quot;&gt;
    &lt;local:MenuItem.RenderTransform&gt;
        &lt;TranslateTransform&gt;&lt;/TranslateTransform&gt;
    &lt;/local:MenuItem.RenderTransform&gt;
&lt;/local:MenuItem&gt;
</pre></p><p>When the button loses the focus, the state resets to the passive one, stopping the animation and resetting the arrow image to the single one:</p><p><pre class="brush: cpp">
void MenuItem::ResetElements()
{
    BitmapImage^ image = ref new BitmapImage(ref new Uri(&quot;ms-appx:///MenuItems/single_arrow.png&quot;));
    MenuImage-&gt;Source = image;
    
    ((Storyboard^)ControlContainer-&gt;Resources-&gt;Lookup(&quot;ArrowAnimator&quot;))-&gt;Stop();
    
    coverRectangle-&gt;Width = initialBarWidth;
    coverActiveRectangle-&gt;Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
</pre></p><p>That’s about as complex as the menu item control will get. The menu container itself can be any <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.grid">Grid</a> or <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.stackpanel">StackPanel</a> control. The way the menu items are used across the game states, there is no need to have a separate unified container.</p><h4>The Main XAML Container &amp; State Changes</h4><p>Going back to <strong>DirectXPage.xaml</strong>, there are several parts of the XAML layout that should be highlighted. First and foremost, the game curtains—the static parts of the screen that are being displayed instead of blacking out parts of the viewport that are not being used when the game runs in landscape mode. Because the game includes a rectangular frame instead of stretching the entire playable area to the size of the screen, there is an unknown amount of unallocated visual space on both the right and left sides of the frame itself:</p><p><pre class="brush: xml">
&lt;Grid HorizontalAlignment=&quot;Left&quot; x:Name=&quot;containerA&quot;&gt;
    &lt;Rectangle Fill=&quot;#09bbe3&quot; /&gt;

    &lt;Rectangle Width=&quot;10&quot; HorizontalAlignment=&quot;Left&quot;&gt;
        &lt;Rectangle.Fill&gt;
            &lt;LinearGradientBrush StartPoint=&quot;0,0&quot; EndPoint=&quot;1,0&quot;&gt;
                &lt;GradientStop Color=&quot;#a000&quot; Offset=&quot;0.0&quot;&gt;&lt;/GradientStop&gt;
                &lt;GradientStop Color=&quot;#0000&quot; Offset=&quot;1.0&quot;&gt;&lt;/GradientStop&gt;
            &lt;/LinearGradientBrush&gt;
        &lt;/Rectangle.Fill&gt;
    &lt;/Rectangle&gt;
&lt;/Grid&gt;

&lt;Grid HorizontalAlignment=&quot;Right&quot; x:Name=&quot;containerB&quot;&gt;
    &lt;Rectangle Fill=&quot;#09bbe3&quot; /&gt;

    &lt;Rectangle Width=&quot;10&quot; HorizontalAlignment=&quot;Right&quot;&gt;
        &lt;Rectangle.Fill&gt;
            &lt;LinearGradientBrush StartPoint=&quot;1,0&quot; EndPoint=&quot;0,0&quot;&gt;
                &lt;GradientStop Color=&quot;#a000&quot; Offset=&quot;0.0&quot;&gt;&lt;/GradientStop&gt;
                &lt;GradientStop Color=&quot;#0000&quot; Offset=&quot;1.0&quot;&gt;&lt;/GradientStop&gt;
            &lt;/LinearGradientBrush&gt;
        &lt;/Rectangle.Fill&gt;
    &lt;/Rectangle&gt;
&lt;/Grid&gt;
</pre></p><p>Although these two grids have set alignments, the actual location on the screen will be set in code-behind because the size will also be re-calculated. Also, I need to make sure that the application is in the full display mode—if it is snapped, there is no need to display the curtains because the visible area will be reduced to an overlay grid.</p><p>The curtain resize and visibility are determined in the UpdateWindowSize method:</p><p><pre class="brush: cpp">
void DirectXPage::UpdateWindowSize()
{
    bool visibility = true;
    if (ApplicationView::Value == ApplicationViewState::Snapped)
            visibility = false;
    
    float margin = (m_renderer-&gt;m_renderTargetSize.Width - 768.0f) / 2.0f;
    if (margin &lt; 2.0)
            visibility = false;
    
    if (visibility)
    {
        containerA-&gt;Width =  margin;
        containerA-&gt;HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Right;
        containerB-&gt;Width =  margin;
        containerB-&gt;HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Left;
        containerA-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
        containerB-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
    }
    else
    {
        containerA-&gt;Visibility = Windows::UI::Xaml::Visibility::Collapsed;
        containerB-&gt;Visibility = Windows::UI::Xaml::Visibility::Collapsed;
    }
}
</pre></p><p>The snippet above ensures that the curtains will only be displayed when there is extra, unused space in addition to the 768 pixels taken by the playable area.</p><p>Let’s take a look at state-specific content that is being displayed whenever the game switches states. Because of the nature of DirectX interaction, there is no way for me to hook to specific event handlers from the native loop. Therefore, I need to constantly check that the content displayed is associated with the current state.</p><p>This can be done with the help of the <strong>SwitchGameState</strong> method:</p><p><pre class="brush: cpp">
void DirectXPage::SwitchGameState()
{
    switch (m_renderer-&gt;CurrentGameState)
            {
            case GameState::GS_FULL_WIN:
                    {
                            grdCompleteWin-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_PLAYING:
                    {
                            Hud-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_MAIN_MENU:
                    {
                            stkMainMenu-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_GAME_OVER:
                    {
                            UpdateResults();
                            ResultPanel-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            grdGameOver-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_SUBMIT_SCORE:
                    {
                            grdSubmitScore-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            txtSubmitScoreView-&gt;Text = StaticDataHelper::Score.ToString();
                            break;
                    }
            case GameState::GS_TOP_SCORES:
                    {
                            grdTopScores-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_WIN:
                    {
                            UpdateResults();
                            grdWinner-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            ResultPanel-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_ABOUT_SCREEN:
                    {
                            grdAbout-&gt;Visibility =  Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_LEVEL_SELECT_SINGLE:
                    {
                            animationBeginTime = 0;
            
                            stkLevelSelector-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            break;
                    }
            case GameState::GS_HOW_TO:
                    {
                            grdHowTo-&gt;Visibility = Windows::UI::Xaml::Visibility::Visible;
                            Storyboard^ howToInitialBoard = (Storyboard^)grdMain-&gt;Resources-&gt;Lookup(&quot;StoryboardChainA&quot;);
                            howToInitialBoard-&gt;Begin();
                            break;
                    }
        default:
                    break;
            }
    
            Storyboard^ loc = (Storyboard^)grdMain-&gt;Resources-&gt;Lookup(&quot;FadingOut&quot;);
            loc-&gt;Begin();
}
</pre></p><p>One thing you’ve probably noticed about the snippet above is the fact that there is no indicator showing that controls are being hidden when the state changes. Just calling <strong>SwitchGameState</strong> in the Update loop would cause multiple controls to be displayed at once. However, there is also the <strong>HideEverything</strong> method that goes through the visual tree and sets the <strong>Visibility</strong> to <strong>Collapsed</strong> for everything:</p><p><pre class="brush: cpp">
void DirectXPage::HideEverything()
{
    for (uint i = 0; i &lt; grdMain-&gt;Children-&gt;Size; i&#43;&#43;)
    {
        grdMain-&gt;Children-&gt;GetAt(i)-&gt;Visibility = Windows::UI::Xaml::Visibility::Collapsed;
    }
}
</pre></p><p>&nbsp;</p><h4>HUD Interaction</h4><p>The Heads-Up Display (HUD) is used to alert the player about the current state of the game and the game character. In FallFury, it is used to display three indicators: how many buttons the character collected, how much time it took the character to get to the current level part, and current character health. It is also the container for the Pause button.</p><p>Here is the visual representation:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D.jpg"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb-1.jpg" alt="clip_image006" width="517" height="331" border="0"></a></p><p>Here is the underlying XAML:</p><p><pre class="brush: xml">
&lt;Grid x:Name=&quot;Hud&quot; VerticalAlignment=&quot;Top&quot; Visibility=&quot;Collapsed&quot;&gt;
    &lt;Grid.RowDefinitions&gt;
        &lt;RowDefinition Height=&quot;80&quot; /&gt;
        &lt;RowDefinition Height=&quot;Auto&quot; /&gt;
    &lt;/Grid.RowDefinitions&gt;
    &lt;Grid.ColumnDefinitions&gt;
        &lt;ColumnDefinition /&gt;
        &lt;ColumnDefinition /&gt;
        &lt;ColumnDefinition /&gt;
        &lt;ColumnDefinition Width=&quot;80&quot; /&gt;
    &lt;/Grid.ColumnDefinitions&gt;

    &lt;Rectangle Fill=&quot;Black&quot; Grid.ColumnSpan=&quot;4&quot; /&gt;

    &lt;Button
        Grid.Column=&quot;0&quot;
        x:Name=&quot;btnPause&quot;
        Click=&quot;btnPause_Click&quot;
        Style=&quot;{StaticResource PauseButton}&quot;&gt;
        &lt;Image Source=&quot;ms-appx:///Assets/HUD/pauseButton.png&quot; Stretch=&quot;None&quot; /
    &lt;/Button&gt;

    &lt;StackPanel Grid.Column=&quot;1&quot; Orientation=&quot;Horizontal&quot;&gt;
        &lt;Image Source=&quot;ms-appx:///Assets/HUD/buttonHud.png&quot; Stretch=&quot;None&quot; /&gt;

        &lt;TextBlock
            x:Name=&quot;txtButtons&quot;
            Text=&quot;0&quot;
            Style=&quot;{StaticResource hudResult}&quot;/&gt;
    &lt;/StackPanel&gt;

    &lt;StackPanel Grid.Column=&quot;2&quot; Orientation=&quot;Horizontal&quot;&gt;
        &lt;Image Source=&quot;ms-appx:///Assets/HUD/clockHud.png&quot; Stretch=&quot;None&quot; /&gt;

        &lt;TextBlock
            x:Name=&quot;txtTimer&quot;
            Text=&quot;00:00&quot;
            Style=&quot;{StaticResource hudResult}&quot;/&gt;
    &lt;/StackPanel&gt;

    &lt;Image
        Grid.Column=&quot;3&quot;
        Source=&quot;ms-appx:///Assets/HUD/heartHud.png&quot;
        Stretch=&quot;None&quot; /&gt;

    &lt;Grid
        Grid.Column=&quot;3&quot;
        Grid.Row=&quot;1&quot;&gt;
        &lt;Rectangle Fill=&quot;Black&quot; Opacity=&quot;.8&quot;/&gt;
        &lt;controls:HealthBar x:Name=&quot;healthBar&quot;&gt;&lt;/controls:HealthBar&gt;
    &lt;/Grid&gt;
&lt;/Grid&gt;
</pre></p><p>As I mentioned before, the DirectX layer cannot directly interact with the XAML layer. Therefore, there needs to be an intermediary binding class. As the game progress changes, the <strong>UpdateHUD</strong> method is called, taking a reference to the current DirectX screen and reading the game data from the character and the <strong>StaticDataHelper</strong> class, which is the container for the time elapsed:</p><p><pre class="brush: cpp">
void DirectXPage::UpdateHud(GamePlayScreen^ playScreen)
{
    healthBar-&gt;Update(playScreen-&gt;GameBear-&gt;CurrentHealth, playScreen-&gt;GameBear-&gt;MaxHealth);
    
    txtButtons-&gt;Text = StaticDataHelper::ButtonsCollected.ToString();
    
    // Find a better built-in string formatting code
    if (m_renderer-&gt;CurrentGameState == GameState::GS_PLAYING &amp;&amp; !(StaticDataHelper::IsPaused) &amp;&amp; playScreen-&gt;IsLevelLoaded)
    {
        StaticDataHelper::SecondsTotal &#43;= m_timer-&gt;Delta;
        
        txtTimer-&gt;Text = StaticDataHelper::GetTimeString((int)StaticDataHelper::SecondsTotal);
    }
}
</pre></p><p>As seen above, part of the HUD is taken by a health indicator control—<strong>HealthBar</strong>. It is a simple composite element made out of two overlaying rectangles, one of which is resized as the bear health changes:</p><p><pre class="brush: xml">
&lt;UserControl
    x:Class=&quot;Coding4Fun.FallFury.Controls.HealthBar&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:local=&quot;using:FallFury&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot;
    d:DesignHeight=&quot;410&quot;
    d:DesignWidth=&quot;20&quot; Height=&quot;410&quot; Width=&quot;20&quot;&gt;
    
    &lt;Grid&gt;
        &lt;StackPanel VerticalAlignment=&quot;Top&quot; Margin=&quot;0, 5, 0,20&quot;&gt;
            &lt;Rectangle Height=&quot;400&quot; Style=&quot;{StaticResource HealthRectangle}&quot; /&gt;
        &lt;/StackPanel&gt;

        &lt;StackPanel VerticalAlignment=&quot;Top&quot; Margin=&quot;0, 5, 0, 10&quot;&gt;
            &lt;Rectangle x:Name=&quot;OverlayStacker&quot; Height=&quot;0&quot; Style=&quot;{StaticResource HealthOverlayRectangle}&quot; /&gt;
        &lt;/StackPanel&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre></p><p>Being of a fixed size, it is fairly easy to calculate the health-to-damage ratio and display that as the size of the overlaid rectangle:</p><p><pre class="brush: cpp">
DependencyProperty^ HealthBar::_MaxHealthProperty = 
    DependencyProperty::Register(&quot;MaxHealth&quot;, 
    double::typeid,
    HealthBar::typeid, 
    nullptr);

DependencyProperty^ HealthBar::_CurrentHealthProperty = 
    DependencyProperty::Register(&quot;CurrentHealth&quot;, 
    double::typeid,
    HealthBar::typeid, 
    nullptr);

void HealthBar::Update(double currentHealth, double maxHealth)
{
    CurrentHealth = currentHealth;
    MaxHealth = maxHealth;
    
    if (CurrentHealth &gt;= 0)
    {
        OverlayStacker-&gt;Height = 400.0 - ((400.0 * CurrentHealth) / MaxHealth);
    }
}
</pre></p><h4>Conclusion</h4><p>Using XAML as a part of a DirectX application does not require the developer to do a massive overhaul of the infrastructure. That said, be mindful when deciding whether to use a hybrid XAML application, as it is much easier to integrate a SwapChainBackgroundPanel with the underlying DirectX configuration from the ground up instead of trying to do so when the DirectX component is completed.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:f25dcd4fcbea4abdab11a1400002dab2">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop</comments>
      <itunes:summary>As mentioned earlier in the series, FallFury does not solely rely on DirectX to display content to the user. As a Windows Store game, FallFury leverages the new Direct2D (XAML) project template, available in Visual Studio 2012.&amp;nbsp; Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-4-XAML-Interop.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. The Concept of a Swap ChainBefore I go into detail about the DirectX and XAML interop in FallFury, I want to cover one important aspect of DirectX development that you need to familiarize yourself with: the swap chain. When your graphics adapter draws on the visual surface, you, as the user, see only minor potential redraws. Internally, however, the device switches buffers that reflect the displayed content, with each buffer representing a frame that has to be drawn. You can deduce from this that any swap chain has at least two buffers that it can switch between. For example, if I want to display my character as being displaced by a specific amount of pixels, the buffer will at the outset present to me the character in its initial position, while the second buffer will be constructed in the background with the proper position adjustments. The first frame, made from the content from the first buffer, will be discarded, and then the second frame will be displayed, and so on. This process occurs at a very high speed that depends on the processing capabilities of the graphics adapter, so the user does not notice the swapping itself. The most common swap chain is composed of two buffers—the screenbuffer and the secondary framebuffer. SwapChainBackgroundPanelDirectX interoperability with XAML simplifies a lot of routine tasks that would otherwise be handled with manual rendering procedures, such as a menu system or a simple game HUD. That being said, the way the XAML workflow is organized in a Direct2D project is quite different </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop</link>
      <pubDate>Wed, 23 Jan 2013 23:57:07 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/04e6/01086880-1f2d-4b77-8261-a7ccc0c804e6/FallFuryPart4_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-4-XAML-Interop/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 3 - Basic Rendering and Movement</title>
      <description><![CDATA[<p>Continuing the FallFury series, in this article I talk about basic game element rendering and character movement. As you already know, the FallFury user experience stack is split across two layers—native DirectX and XAML. Here, I will only be talking about the native DirectX component.&nbsp; Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement">http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement</a>&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>The Background</h4><p>Each game screen in FallFury has a moving background that creates the illusion of a fall. The way the screen is designed, it simulates vertical <a href="http://en.wikipedia.org/wiki/Parallax_scrolling">parallax scrolling</a>, as the background moves faster than the overlaid objects. There is a simple way to make background movement possible without actually having to replicate parts of the texture and render them all over again. Take a look at this image, showcasing the process:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B2%5D-6.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb-7.png" alt="image" width="610" height="480" border="0"></a></p><p>First of all, two textures are loaded that, connected at the bottom, create the illusion of a single texture. In the beginning, texture A takes the entire screen and texture B is positioned directly underneath it, with a non-existing gap between them. To initiate the scrolling, texture A is being displaced vertically by an arbitrary number of pixels, and texture B follows it at the same pace. As texture B reaches the zero point (top of the viewport), texture A is no longer visible, therefore it is displaced vertically to be below texture B. This cycle can be repeated as many times as necessary during gameplay as well as while the user is in the menu.</p><p>Let’s take a look at the code that makes it possible, starting with the main menu screen:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-8.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B1%5D-5.png" alt="image" width="623" height="354" border="0"></a></p><p>First of all, you need to be aware that every game screen is automatically inheriting the properties and capabilities of base class <strong>GameScreenBase</strong>. This is the class the offers the foundation both for basic texture loading and movement:</p><p><pre class="brush: cpp">
protected private:
    // Core background textures
    Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;                    m_backgroundBlockA;
    Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt;                    m_backgroundBlockB;

void MoveBackground(float velocity);
</pre></p><p>It also offers the core texture containers for the overlaid elements that are present in most screens, such as clouds:</p><p><pre class="brush: cpp">
// Overlayed clouds
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt; m_overlayA;
Microsoft::WRL::ComPtr&lt;ID3D11Texture2D&gt; m_overlayB;
</pre></p><p>The overlay movement is inherently dependent on the base background displacement and can be adjusted relative to the initial velocity. Let’s take a look at <strong>GameScreenBase.cpp</strong>, specifically at <strong>MoveBackground</strong>:</p><p><pre class="brush: cpp">
void GameScreenBase::MoveBackground(float velocity)
{
    if (m_backgroundPositionA &lt;= -BACKGROUND_MIDPOINT)
        m_backgroundPositionA = m_backgroundPositionB &#43; (BACKGROUND_MIDPOINT * 2);

    if (m_backgroundPositionB &lt;= -BACKGROUND_MIDPOINT)
        m_backgroundPositionB = m_backgroundPositionA &#43; (BACKGROUND_MIDPOINT * 2);

    m_backgroundPositionA -= velocity;
    m_backgroundPositionB -= velocity;
}
</pre></p><p>The BACKGROUND_MIDPOINT value is relative to the height of the background texture. As we are working with a variable screen size, given that tablets and desktops do not have the same resolution, the movement has to be adjusted accordingly. One way, however, to ensure the proper texture positioning would be to place it in relation to its previous instance. Hence, this snippet in <strong>UpdateWindowSize</strong>:</p><p><pre class="brush: cpp">
BACKGROUND_MIDPOINT = 1366.0f / 2.0f;
m_backgroundPositionA = BACKGROUND_MIDPOINT;
m_backgroundPositionB = m_backgroundPositionA * 3;
</pre></p><p>Because overlays are not necessarily a part of every screen, I am not including the <strong>MoveOverlay</strong> method in the base class. Let’s now take a look at <strong>MenuScreen.cpp</strong>. Take a look at the Load method and you will see several lines that prepare the background and overlays:</p><p><pre class="brush: cpp">
m_loader = ref new BasicLoader(Manager-&gt;m_d3dDevice.Get(), Manager-&gt;m_wicFactory.Get());

m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_blue_a.png&quot;, &amp;m_backgroundBlockA, nullptr);
m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_blue_b.png&quot;, &amp;m_backgroundBlockB, nullptr);
m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_a.png&quot;, &amp;m_overlayA, nullptr);
m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_b.png&quot;, &amp;m_overlayB, nullptr);

CurrentSpriteBatch-&gt;AddTexture(m_backgroundBlockA.Get());
CurrentSpriteBatch-&gt;AddTexture(m_backgroundBlockB.Get());
CurrentSpriteBatch-&gt;AddTexture(m_overlayA.Get());
CurrentSpriteBatch-&gt;AddTexture(m_overlayB.Get());
</pre></p><p>The <strong>BasicLoader</strong> class was imported from the <a href="http://code.msdn.microsoft.com/windowsapps/Direct3D-sprite-sample-97ae6262">Direct3D sprite sample</a>. A call to LoadTexture will read the data from a DDS or PNG file and output the data in an <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476635%28v=vs.85%29.aspx">ID3D11Texture2D</a> object. Once loaded, the texture is added to the <strong>SpriteBatch</strong> instance associated with the screen, also declared as a part of <strong>GameScreenBase</strong>.</p><p>Depending on the screen, this procedure might have to be done for multiple textures, as you will see later in this article. Each page also has two timed loops—<strong>RenderScreen</strong> and <strong>Update</strong>. RenderScreen is responsible for taking everything from the SpriteBatch instance and showing it to the user. If you’ve used the <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritebatch.aspx">XNA SpriteBatch</a> before, you are aware that you need to start the drawing cycle by calling <strong>Begin</strong> and end it by calling <strong>End</strong>. The same applies here:</p><p><pre class="brush: cpp">
CurrentSpriteBatch-&gt;Begin();

CurrentSpriteBatch-&gt;Draw(
    m_backgroundBlockA.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2, m_backgroundPositionA),
    PositionUnits::DIPs,
    m_screenSize,
    SizeUnits::Pixels);

CurrentSpriteBatch-&gt;Draw(
    m_backgroundBlockB.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2 ,m_backgroundPositionB),
    PositionUnits::DIPs,
    m_screenSize,
    SizeUnits::Pixels);

if (m_showBear-&gt;IsLoaded)
    m_showBear-&gt;Render();

if (m_showMonster-&gt;IsLoaded)
    m_showMonster-&gt;Render();

CurrentSpriteBatch-&gt;Draw(
    m_overlayA.Get(),
    float2(Manager-&gt;m_windowBounds.Width/2, m_backgroundPositionA),
    PositionUnits::DIPs,
    m_screenSize,
    SizeUnits::Pixels);

CurrentSpriteBatch-&gt;Draw(
    m_overlayB.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2 ,m_backgroundPositionB),
    PositionUnits::DIPs,
    m_screenSize,
    SizeUnits::Pixels);

CurrentSpriteBatch-&gt;End();
</pre></p><p>The current overloaded <strong>Draw</strong> call gets the following items:</p><ul><li>The texture object </li><li>The position where the object has to be drawn on the screen </li><li>The way the object is positioned (can also be a normalized value or a pixel value) </li><li>The size of the texture (stretching may occur) </li><li>The type of the size value (in this case, I am using pixels, but can also be normalized) </li></ul><p>The order in which the <strong>Draw</strong> calls are arranged determines the order of objects drawn on the screen. The calls on top will place texture objects at the bottom of the rendering stack, and the calls at the end will place the objects at the top of the stack.</p><h4>The Gameplay Screen Background &amp; Overlays</h4><p>Let’s move on to the arguably most critical screen in the project, <strong>GamePlayScreen.cpp</strong>. There are a few nuances that differentiate it from any other screen—in particular, the background loading routine.</p><p>For every game, there is a different level type that is being used. With each level type, there is a different combination of a background and the overlay. Currently, there are four supported level types:</p><ul><li>Space </li><li>Nightmare </li><li>Magic Bean </li><li>Dream </li></ul><p>When the proper level is detected and the metadata is loaded from the associated XML file (more about this process later on in the series), the level textures are loaded into memory:</p><p><pre class="brush: cpp">
switch (m_currentLevelType)
{
    case LevelType::SPACE:
    {
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_dark_blue_a.png&quot;, &amp;m_backgroundBlockA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_dark_blue_b.png&quot;, &amp;m_backgroundBlockB, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\star_overlay_a.png&quot;, &amp;m_overlayA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\star_overlay_b.png&quot;, &amp;m_overlayB, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\galaxy_overlay_a.png&quot;, &amp;m_overlayGalaxyA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\galaxy_overlay_b.png&quot;, &amp;m_overlayGalaxyB, nullptr);
        
        CurrentSpriteBatch-&gt;AddTexture(m_overlayGalaxyA.Get());
        CurrentSpriteBatch-&gt;AddTexture(m_overlayGalaxyB.Get());
        break;
    }
    case LevelType::NIGHTMARE:
    {
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_red_a.png&quot;, &amp;m_backgroundBlockA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_red_b.png&quot;, &amp;m_backgroundBlockB, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_a.png&quot;, &amp;m_overlayA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_b.png&quot;, &amp;m_overlayB, nullptr);
        break;
    }
    case LevelType::MAGIC_BEANS:
    {
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_blue_a.png&quot;, &amp;m_backgroundBlockA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\generic_blue_b.png&quot;, &amp;m_backgroundBlockB, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_a.png&quot;, &amp;m_overlayA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_b.png&quot;, &amp;m_overlayB, nullptr);
        
        break;
    }
    case LevelType::DREAM:
    {
        m_loader-&gt;LoadTexture(&quot;DDS\\Levels\\Dream\\TEST_backgroundDream_01.dds&quot;, &amp;m_backgroundBlockA, nullptr);
        m_loader-&gt;LoadTexture(&quot;DDS\\Levels\\Dream\\TEST_backgroundDream_02.dds&quot;, &amp;m_backgroundBlockB, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_a.png&quot;, &amp;m_overlayA, nullptr);
        m_loader-&gt;LoadTexture(&quot;Assets\\Backgrounds\\cloud_overlay_b.png&quot;, &amp;m_overlayB, nullptr);
        break;
    }
}
</pre></p><p>This way, no unnecessary textures are loaded. A screen-based level flag allows me to control the incoming assets. At this point, the level environment does not change dynamically, so it is safe to assume that the textures should be loaded on a per-level basis.</p><p>The RenderScreen method is called in the same manner as in the menu screen, with the moving background and overlays located at the bottom of the rendering stack:</p><p><pre class="brush: cpp">
CurrentSpriteBatch-&gt;Draw(
    m_backgroundBlockA.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2, m_backgroundPositionA),
    PositionUnits::DIPs,
    m_screenSize,
    SizeUnits::Pixels);

CurrentSpriteBatch-&gt;Draw(
    m_backgroundBlockB.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2, m_backgroundPositionB),
    PositionUnits::DIPs,
    m_screenSize,
    SizeUnits::Pixels);

CurrentSpriteBatch-&gt;Draw(
    m_overlayA.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2, m_overlayPositionA),
    PositionUnits::DIPs,
    float2(768.0f, 1366.0f),
    SizeUnits::Pixels);

CurrentSpriteBatch-&gt;Draw(
    m_overlayB.Get(),
    float2(Manager-&gt;m_windowBounds.Width / 2, m_overlayPositionB),
    PositionUnits::DIPs,
    float2(768.0f, 1366.0f),
    SizeUnits::Pixels);
</pre></p><h4>Character Movement</h4><p>As you are now aware of the basic screen structure and how the basic rendering process is built, let’s take a look at how the main game character moves on the screen. Falling down, the teddy bear also needs to move left and right to ensure that he is able to pick up power-ups and buttons as well as avoid obstacles and enemy ammo.</p><p>There are several important considerations here. The most important one is to not assume that the user will have a specific input device. Potential movement controllers include a keyboard, the mouse, the touch screen and the accelerometer. In the most common scenarios, the desktop machines will not have an accelerometer, and the tablet computers will not have a constantly attached keyboard and a mouse. In FallFury, I decided to leverage all potential input engines and let the user choose the best option for himself.</p><p>When the current GamePlayScreen instance loads, I am attempting to get access to the system accelerometer device:</p><p><pre class="brush: cpp">
m_systemAccelerometer = Windows::Devices::Sensors::Accelerometer::GetDefault();
</pre></p><p><strong>m_systemAccelerometer</strong> is of type <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.sensors.accelerometer">Windows::Devices::Sensors::Accelerometer</a> and is declared in <strong>GamePlayScreen.h</strong>. If an accelerometer is detected, I need to bind it to a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.sensors.accelerometer.readingchanged">ReadingChanged</a> event handler that will give me the current G-force transformed into X, Y, and Z displacement:</p><p><pre class="brush: cpp">
if (m_systemAccelerometer != nullptr)
{
    m_systemAccelerometer-&gt;ReadingChanged &#43;= ref new TypedEventHandler&lt;Accelerometer^, AccelerometerReadingChangedEventArgs^&gt;
            (this, &amp;GamePlayScreen::AccelerometerReadingChanged);
}
</pre></p><p><strong>ReadingChanged</strong> itself does not participate in updating the position for the character, but rather passes the current values to <strong>m_xAcceleration</strong>, which is later used in the <strong>Update</strong> method:</p><p><pre class="brush: cpp">
void GamePlayScreen::AccelerometerReadingChanged(_In_ Accelerometer^ accelerometer, _In_ AccelerometerReadingChangedEventArgs^ args)
{
    if (StaticDataHelper::IsAccelerometerEnabled)
    {
        auto currentOrientation = DisplayProperties::CurrentOrientation;
        float accelValue;
        
        if (currentOrientation == DisplayOrientations::Portrait)
                    accelValue = args-&gt;Reading-&gt;AccelerationY;
        else if (currentOrientation == DisplayOrientations::PortraitFlipped)
                    accelValue = -args-&gt;Reading-&gt;AccelerationY;
        else if (currentOrientation == DisplayOrientations::Landscape)
                    accelValue = args-&gt;Reading-&gt;AccelerationX;
        else if (currentOrientation == DisplayOrientations::LandscapeFlipped)
                    accelValue = -args-&gt;Reading-&gt;AccelerationX;
        else
                    accelValue = 0.0f;
        
        if (StaticDataHelper::IsAccelerometerInverted)
                    m_xAcceleration = -accelValue;
        else
                    m_xAcceleration = accelValue;
    }
}
</pre></p><p>The reason for this lies in the fact that <strong>ReadingChanged</strong> is triggered at a much lower rate than the <strong>Update</strong> loop. If the character position would be adjusted through the core accelerometer event handler, the result would be choppy (“step-by-step”) movement instead of a smooth transition.</p><p>Notice, also, that depending on the screen orientation, I need to get the acceleration either on the X- or Y-axes. Since an accelerometer is detected, I am assuming that the device that’s being used is a tablet. Therefore, it can have auto-rotate enabled, which means that the reference axis (horizontal) might change depending on how the user holds the device. <a href="http://msdn.microsoft.com/en-US/library/windowsphone/develop/windows.graphics.display.displayproperties.currentorientation.aspx">DisplayProperties::CurrentOrientation</a> can give me the current orientation, whether portrait (Y acceleration value) or landscape (X acceleration value):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B8%5D-3.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B2%5D-7.png" alt="image" width="622" height="349" border="0"></a></p><p>As with many other titles, the user may invert the movement based on the accelerometer reading. For example, if the device is tilted to the right, the character will move to the left, and vice-versa. The effect is easily achieved by negating the current reading, regardless of the axis it is relying on.</p><p>Obviously, as the character moves, there should be boundaries that restrict the movement within the context of the current game screen. To get the correct screen bounds, <strong>GameScreenBase</strong>, the foundation class for every screen, sets four properties: <strong>LoBoundX</strong>, <strong>HiBoundX</strong>, <strong>LoBoundY</strong> and <strong>HiBoundY</strong>:</p><p><pre class="brush: cpp">
LoBoundX = (rWidth - 768.0f) / 2.0f;
HiBoundX = LoBoundX &#43; 768.0f;

LoBoundY = 0;
HiBoundY = LoBoundY &#43; rHeight;
</pre></p><p><strong>LoBoundX</strong> is the leftmost limit for the horizontal playable area and <strong>HiBoundX</strong> is the rightmost limit for the same horizontal area. <strong>LoBoundY</strong> and <strong>HiBoundY</strong> are responsible for carrying the limits for the vertical space. All four boundary values are relative to the screen size:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B11%5D-2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B3%5D-7.png" alt="image" width="624" height="355" border="0"></a></p><p>To consistently get the correct X boundary no matter the screen size, the playable area is set to a fixed width of 768 pixels. The rest of the screen is accordingly cancelled out and the remaining area split in two. The original X point (zero) is added to the curtain size and that way there is the leftmost X boundary. The Y boundaries are simply obtained from the screen height, as there are no gameplay experience restrictions in that domain.</p><p>The bear position is updated in the Update loop in the game screen. There are several parameters that need to be adjusted, such as the vertical velocity, the bear rotation on tilt and the horizontal displacement.</p><p>When the level just starts, the bear falls faster until he reaches the standard static Y point. Because of screen size differences, this should not be done by comparing the pixel distance but rather by utilizing a ratio built from the current bear Y position and the high Y boundary:</p><p><pre class="brush: cpp">
if ((GameBear-&gt;Position.y / HiBoundY) &lt; 0.19f)
{
    GameBear-&gt;Position.y &#43;= GameBear-&gt;Velocity.y * (3.2f);
}
</pre></p><p>Assuming that the game is not paused, and thus the background is moving, the bear Y position should be adjusted relative to the current velocity set for the background scrolling. Because of how parallax scrolling works, the bear velocity has to be higher than the initial screen movement. Therefore, it is multiplied by a fixed value independent of the level played:</p><p><pre class="brush: cpp">
if (!m_isBackgroundMoving)
{
    if (GameBear-&gt;Position.y &gt; m_screenSize.y)
    {
        Manager-&gt;CurrentGameState = GameState::GS_GAME_OVER;
    }
    else
    {
        GameBear-&gt;Position.y &#43;= GameBear-&gt;Velocity.y * 1.5f;
    }
}
</pre></p><p>In the statement above, there is also an extra condition that verifies whether the bear is below the low Y boundary. If it is, then the game is over. This is imposed by a game animation that takes the bear off the Y limits, meaning that the bear is dead.</p><p>Bear rotation is based on the current X acceleration, but the bear shouldn’t rotate 360 degrees. To limit the rotation, there is a rotation threshold set (value taken in radians) that is being checked before rotating the character:</p><p><pre class="brush: cpp">
float compositeRotation = GameBear-&gt;Rotation - (float)m_xAcceleration / 10.0f;
if (compositeRotation &lt; m_rotationThreshold &amp;&amp; compositeRotation &gt; -m_rotationThreshold)
    GameBear-&gt;Rotation = compositeRotation;
</pre></p><p>The composite value lets me verify the perspective rotation without actually assigning it to the bear. If it is within the imposed threshold, only then will the bear rotation be adjusted.</p><p>Using the composite value approach is also efficient when performing the horizontal displacement adjustment. The initial value is composed of the current position and the X-based acceleration multiplied by a dynamic multiplier value to create the inertia effect:</p><p><pre class="brush: cpp">
float compositePosition = GameBear-&gt;Position.x &#43; ((float)m_xAcceleration * m_accelerationMultiplier);

if (m_xAcceleration &lt; 0)
    compositePosition -= 100.0f;
else
    compositePosition &#43;= 100.0f;

if (Manager-&gt;IsWithinScreenBoundaries(float2(compositePosition, GameBear-&gt;Position.y)))
{
    GameBear-&gt;Position.x &#43;= (float)m_xAcceleration * m_accelerationMultiplier;
}
else
{
    if (GameBear-&gt;Position.x &gt; HiBoundX)
    {
        GameBear-&gt;Position.x = HiBoundX - 180.0f;
    }
    else if (GameBear-&gt;Position.x &lt; LoBoundX)
    {
        GameBear-&gt;Position.x = LoBoundX &#43; 180.0f;
    }
}
</pre></p><p>If the bear is attempting to hit a “wall” (screen limit), its position is set back to the one barely prior to the limit. By doing this, I am avoiding locking the character on the side of the screen.</p><p>There is something in this snippet above that you might not be aware of—a reference to <strong>Manager-&gt;IsWithinScreenBoundaries</strong>. This method belongs to the ScreenManager (ScreenManager.cpp) class—a utility class that ensures the proper screen is displayed depending on the current game mode, and also allows control of mouse actions and boundary checks:</p><p><pre class="brush: cpp">
bool ScreenManager::IsWithinScreenBoundaries(float2 position)
{
    if (position.x &lt; CurrentGameScreen-&gt;LoBoundX || position.x &gt; CurrentGameScreen-&gt;HiBoundX || position.y &lt; CurrentGameScreen-&gt;LoBoundY || position.y &gt; CurrentGameScreen-&gt;HiBoundY)
            return false;
    else
            return true;
}
</pre></p><p>You saw how the movement is accomplished with the help of the accelerometer. Let’s take a look at how a keyboard can be used to do the same thing. There is a <strong>HandleKeyInput</strong> method, exposed through the <strong>GamePlayScreen</strong> class. As a matter of fact, <strong>HandleKeyInput</strong> is wired into the <strong>GameScreenBase</strong> class, therefore if a specific combination needs to be handled outside the context of the game play screen, it can be:</p><p><pre class="brush: cpp">
void GamePlayScreen::HandleKeyInput(Windows::System::VirtualKey key)
{
    if (key == Windows::System::VirtualKey::Right)
    {
        if (GameBear-&gt;IsWithinScreenBoundaries(GameBear-&gt;Size.x, 0.0f, GetScreenBounds()))
        {
            GameBear-&gt;Direction = TurningState::RIGHT;
            
            m_xAcceleration = 0.8f;
            
            if (GameBear-&gt;Rotation &gt;= -m_rotationThreshold)
                            GameBear-&gt;Rotation -= 0.02f;
        }
    }
    else if (key == Windows::System::VirtualKey::Left)
    {
        if (GameBear-&gt;IsWithinScreenBoundaries(-GameBear-&gt;Size.x, 0.0f, GetScreenBounds()))
        {
            GameBear-&gt;Direction = TurningState::LEFT;
            
            m_xAcceleration = -0.8f;
            
            if (GameBear-&gt;Rotation &lt;= m_rotationThreshold)
                            GameBear-&gt;Rotation &#43;= 0.02f;
        }
    }
}
</pre></p><p>As the accelerometer is no longer influencing the rotation or displacement, both indicators have to be manipulated through key presses. There are still standard thresholds in place to limit the potential incorrect movement, but the idea remains the same. This method is being called from the XAML page, which is overlaid on top of the DirectX renders:</p><p><pre class="brush: xml">
&lt;SwapChainBackgroundPanel
    x:Class=&quot;Coding4Fun.FallFury.DirectXPage&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:local=&quot;using:Coding4Fun.FallFury&quot; x:Name=&quot;XAMLPage&quot;
    xmlns:controls=&quot;using:Coding4Fun.FallFury.Controls&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot; Loaded=&quot;OnLoaded&quot; KeyDown=&quot;OnKeyDown&quot; LayoutUpdated=&quot;XAMLPage_LayoutUpdated&quot;&gt;
</pre><pre class="brush: cpp">
void DirectXPage::OnKeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
    m_renderer-&gt;CurrentGameScreen-&gt;HandleKeyInput(e-&gt;Key);
}
</pre></p><p>When the keyboard is not available, movement can be controlled with the help of a mouse. Again, with standard event handlers, I am simply using <strong>OnPointerMoved</strong>:</p><p><pre class="brush: cpp">
void GamePlayScreen::OnPointerMoved(Windows::UI::Core::PointerEventArgs^ args)
{
    if (StaticDataHelper::IsMouseEnabled)
    {
        if (GameBear != nullptr)
        {
            m_touchCounter&#43;&#43;;
            if (GameBear-&gt;IsWithinScreenBoundaries(GameBear-&gt;Size.x, 0.0f, GetScreenBounds()))
            {
                m_xAcceleration = (args-&gt;CurrentPoint-&gt;RawPosition.X - GameBear-&gt;Position.x) / m_screenSize.x;
            }
        }
    }
}
</pre></p><p>By using this method, the bear will accelerate to the point where the mouse cursor is located, having a higher velocity the further it is located from the cursor. Once again, this creates the inertia visualization.</p><h4>Conclusion</h4><p>Concluding Part 3 of the series, remember that because Windows 8 is not a tablet-only OS, some users might have different input devices. Try to accommodate as many of those as possible.</p><p>The next article in this series will focus on the XAML overlay used in FallFury.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:4c48bfe7230449a1af4ca13f017fd4e4">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement</comments>
      <itunes:summary>Continuing the FallFury series, in this article I talk about basic game element rendering and character movement. As you already know, the FallFury user experience stack is split across two layers—native DirectX and XAML. Here, I will only be talking about the native DirectX component.&amp;nbsp; Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-3-Basic-Rendering-and-Movement&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. The BackgroundEach game screen in FallFury has a moving background that creates the illusion of a fall. The way the screen is designed, it simulates vertical parallax scrolling, as the background moves faster than the overlaid objects. There is a simple way to make background movement possible without actually having to replicate parts of the texture and render them all over again. Take a look at this image, showcasing the process:  First of all, two textures are loaded that, connected at the bottom, create the illusion of a single texture. In the beginning, texture A takes the entire screen and texture B is positioned directly underneath it, with a non-existing gap between them. To initiate the scrolling, texture A is being displaced vertically by an arbitrary number of pixels, and texture B follows it at the same pace. As texture B reaches the zero point (top of the viewport), texture A is no longer visible, therefore it is displaced vertically to be below texture B. This cycle can be repeated as many times as necessary during gameplay as well as while the user is in the menu. Let’s take a look at the code that makes it possible, starting with the main menu screen:  First of all, you need to be aware that every game screen is automatically inheriting the properties and capabilities of base class GameScreenBase. This is the class the offers the foundation both for basic texture loading and movement: 
protected private:
    // Core background textur</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement</link>
      <pubDate>Wed, 23 Jan 2013 23:57:03 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/f2a1/9afdc0cb-6045-4e66-97d6-89d9297bf2a1/FallFuryPart3_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-3-Basic-Rendering-and-Movement/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 2 - Shaders</title>
      <description><![CDATA[<h4>Introduction to Shaders</h4><p>FallFury not only relies on standard C&#43;&#43;/C# and XAML code, but also on shaders. This article is intended for developers who are not aware of what shaders are and want to know how to use them in their projects. I will talk about creating shaders, as well as the shaders used in my project.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-2-Shaders">http://channel9.msdn.com/Series/FallFury/Part-2-Shaders</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Code on GPU</h4><p>In simple terms, shaders are small programs that are executed on the Graphical Processing Unit (GPU) instead of the Central Processing Unit (CPU). In recent years, we’ve seen a major spike in the capabilities of graphic devices, allowing hardware manufacturers to design an execution layer tied to the GPU, therefore being able to target device-specific manipulations to a highly optimized unit. Shaders are not used for simple calculations, but rather for image processing. For example, a shader can be used to adjust image lighting or colors.</p><p>Modern GPUs give access to the rendering pipeline that allows developers to execute arbitrary image processing code. This is a step forward from a fixed-function pipeline that was present in older GPUs, where image processing tasks were integrated into the hardware unit and were only able to perform a limited set of actions, such as transforms. Unlike the rendering pipeline, the fixed-function pipeline was not programmable, therefore the developers were often tied to the hardware they used for offering specific game effects, in some cases having to resort to software-based adjustments.</p><h4>Types of Shaders</h4><p>There are different types of image manipulations that can be performed on a given input, and so there are different types of shaders designed to handle that. Currently, we can highlight three main shader types:</p><ul><li><strong>Vertex shaders</strong> – because what the user sees on the screen is not really three-dimensional, but rather a three-dimensional simulation in a 2D space, vertex shaders translate the coordinates of a vector in 3D space in relation to the 2D frame. Vertex shaders are executed one time per vector passed to the GPU. Typically, vectors carry data related to their position and the coordinate of the bound texture as well as color. A vertex shader is able to manipulate all these properties, but there is never a situation where a new vertex is created as a result of the execution. </li><li><strong>Pixel shaders</strong> – these programs are executed on the GPU in relation to every passed pixel, working on a much lower level. For example, if you want specific pixels adjusted for lighting or 3D bump mapping, a pixel shader can provide the desired effect for a surface. Rarely, there are situations where only a few pixels should be re-adjusted at once. Pixel shaders are often run with an input of millions of pixels, resulting in complex effects. </li><li><strong>Geometry shaders</strong> – these shaders are the next progression from vertex shaders, introduced with DirectX 10. The developer is able to pass specific primitives as input and either have the output represent the modified version of what was passed to the program or have new primitives, such as triangles, be generated as a result. Geometry shaders are always executed on post-vertex processing in the rendering pipeline. When vertex shader execution is completed, geometry shaders step in, if present. Geometry shaders can be used to refine the level of detail of a specific object. For example, when an object is closer or further away from the viewport camera, the mesh would have to be refined to minimize the rendering load. </li></ul><p>FallFury uses all these shader types as a part of the game.</p><h4>Enough Talk, Let’s Code</h4><p>Now that you are aware of what shaders are, let’s write some sample code and test it. It is worth mentioning that shaders are not written in a standard high-level language, but rather in a language defined by the environment the shader is used in. For Direct3D, this is the High-Level Shader Language, or HLSL. It is somewhat similar to C, but with some specific nuances.</p><p>Start by creating a test Direct3D Windows Store application:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B3%5D-3.jpg"><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb-4.jpg" alt="clip_image002" width="624" height="380" border="0"></a></p><p>If you create and run this sample application, you will see that the output of it is a simple 3D spinning cube:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-2.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-3.jpg" alt="clip_image004" width="435" height="243" border="0"></a></p><p>You probably also noticed that there are two shaders that are a component part of the newly created solution: <strong>SimplePixelShader.hlsl</strong> and <strong>SimpleVertexShader.hlsl</strong>. Take a look inside the pixel shader:</p><p><pre class="brush: cpp">
struct PixelShaderInput
{
    float4 pos : SV_POSITION;
    float3 color : COLOR0;
};

float4 main(PixelShaderInput input) : SV_TARGET
{
    return float4(input.color,1.0f);
}
</pre></p><p>First of all, there is a PixelShaderInput <a>struct</a><a name="_msoanchor_1"></a>[DW1] . It represents a single pixel – it has a float4 field that represents the position of the pixel and a float3 field that represents the RGB pixel color. The field itself is also marked by a predefined type, such as SV_POSITION or COLOR. This is a string that determines the use of the field. You can read more about the shader semantics <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx">here</a>.</p><p>The strings that are prefixed with SV_ are representing system-value semantics. Those have special meaning in the pipeline during the processing stages. In the pixel shader above, SV_POSITION will always mean the pixel position.</p><p>Look at what is being returned from the pixel shader—instead of the standard float3 color indicator, you are now returning a float4, which couples the existing value, input.color, with a 1.0f float value that represents the alpha-channel value. Remember, that inside shaders the color is clamped between 0 and 1 instead of the standard 255-value limit.</p><p>Since the cube rendering mechanism is already in place, let’s experiment with the pixel shader a bit. You’ve already got the float4 color representation:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B3%5D.png"><img title="clip_image006" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006_thumb.png" alt="clip_image006" width="580" height="157" border="0"></a></p><p>You can set any of these values to 1.0 to return the solid color, so let’s do that. Let’s render the cube green. Modify the return statement to be this:</p><p>return float4(0.0, 1.0, 0.0, 1.0);</p><p>At this point, if you will run the program you will get a rendering very similar to this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B3%5D-1.jpg"><img title="clip_image008" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008_thumb-2.jpg" alt="clip_image008" width="624" height="346" border="0"></a></p><p>This is a good start.. Now, let’s now take a look at the vertex shader in the project. By default, you get this:</p><p><pre class="brush: cpp">
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
    matrix model;
    matrix view;
    matrix projection;
};

struct VertexShaderInput
{
    float3 pos : POSITION;
    float3 color : COLOR0;
};

struct VertexShaderOutput
{
    float4 pos : SV_POSITION;
    float3 color : COLOR0;
};

VertexShaderOutput main(VertexShaderInput input)
{
    VertexShaderOutput output;
    float4 pos = float4(input.pos, 1.0f);
    
    pos = mul(pos, model);
    pos = mul(pos, view);
    pos = mul(pos, projection);
    output.pos = pos;
    
    // Pass through the color without modification.
    output.color = input.color;
    
    return output;
}
</pre></p><p>There are a couple of differences here compared to the above mentioned pixel shader:</p><ul><li><strong>cbuffer ModelViewProjectionConstantBuffer</strong> – represents a constant buffer that contains three matrices, to which vertices are related—the model, view and projection matrices. Constant buffers are interesting structures that have been optimized to allow block-wise updates, where multiple constants are grouped in one boxed unit and can be updated simultaneously instead of having a one-by-one iterative update cycle. </li><li><strong>struct VertexShaderInput</strong> – vertices are passed one-by-one to the shader, and this specific structure represents the input. Notice that it carries the 3D representation of the vertex position as well as its RGB color value. </li><li><strong>struct VertexShaderOutput </strong>– the final processed output, which now carries the position in relation to all three matrices mentioned above as well as the processed color. Notice that the fourth value is the camera distance in the demo. </li><li><strong>VertexShaderOutput main(VertexShaderInput input) </strong>– this is the main function that performs the vertex processing. Initially, it performs the position adjustment relative to the camera and then uses <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb509628(v=vs.85).aspx">mul</a>, a built-in function that multiplies matrices, to represent the current vertices in the projected space. </li></ul><p>So let’s play around with what we have in stock. Take a look at the main function and how initially, the float3-based position is transformed to contain the camera distance:</p><p><pre class="brush: cpp">
float4 pos = float4(input.pos, 1.0f);
</pre></p><p>This position is normalized in relation to the current viewport. Afterwards, the vertex is transformed in the current 3D space (relative to three matrices – model, view, and projection):</p><p><pre class="brush: cpp">
pos = mul(pos, model);
pos = mul(pos, view);

pos = mul(pos, projection);

output.pos = pos;
</pre></p><p>As with the pixel shader, these are some very basic manipulations. Let’s flip the cube upside-down. To do this, we need to apply a rotation transformation. Here is an interesting piece of advice—when working with manipulations in shaders, make sure that you know basic matrix operations.</p><p>For example, to perform a simple 2D rotation, you need to use the <a href="http://en.wikipedia.org/wiki/Rotation_matrix">rotation matrix</a>:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image009%5B3%5D.png"><img title="clip_image009" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image009_thumb.png" alt="clip_image009" width="169" height="48" border="0"></a></p><p>But since we’re in 3D space, we not only have the X and Y coordinates, which relate to the matrix above, but also the Z coordinate. Therefore, a different method should be applied. There are three fundamental matrices that can be used to rotate an object around the three possible axes:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image011%5B3%5D.png"><img title="clip_image011" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image011_thumb.png" alt="clip_image011" width="236" height="285" border="0"></a></p><p>For now, we want to rotate the cube along the X-axis. To do this, inside the main function, we need to declare a constant that represents the rotation angle, in radians:</p><p><pre class="brush: cpp">
const float angle = 1.3962634;
</pre></p><p>Looking at the matrix above, we need to find out the sine and cosine of the given angle. When working with vertex shaders, HLSL offers a built-in function, called <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb147382(v=vs.85).aspx">sincos</a> that is able to get both values from an input value:</p><p><pre class="brush: cpp">
float cosLength, sinLength;
sincos(angle, sinLength, cosLength);
</pre></p><p>Now you need to declare the rotation matrix. Again, HLSL comes with some built-in capabilities to declare matrices and set their values:</p><p><pre class="brush: cpp">
float3x3 xAxisRotation = { 
    1.0, 0.0, 0.0, // Row 1
    0, cosLength, -sinLength, // Row 2
    0, sinLength, cosLength}; // Row 3
</pre></p><p>&nbsp;</p><p>The standard format for matrix declaration in this case follows the following pattern:</p><p>Matrix&lt;type,size&gt; localName</p><p>For matrix multiplication, we can once again leverage the mul function:</p><p><pre class="brush: cpp">
float3 temporaryPosition;
temporaryPosition = mul(input.pos,xAxisRotation);
</pre></p><p>Now we can normalize the position to a float4 value that also includes the camera distance:</p><p><pre class="brush: cpp">
float4 pos = float4(temporaryPosition, 1.0f);
</pre></p><p>The rest of the transformation procedures can be taken directly from the original shader, multiplying the float4 position by the model, view, and projection matrices. Your entire main function should now look like this:</p><p><pre class="brush: cpp">
VertexShaderOutput main(VertexShaderInput input)
{
    VertexShaderOutput output;

    const float angle = 1.3962634;
    float cosLength, sinLength;
    sincos(angle, sinLength, cosLength);

    float3x3 xAxisRotation = { 
        1.0, 0.0, 0.0, // Row 1
        0, cosLength, -sinLength, // Row 2
        0, sinLength, cosLength}; // Row 3

    float3 temporaryPosition;
    temporaryPosition = mul(input.pos,xAxisRotation);
    float4 pos = float4(temporaryPosition, 1.0f);

    // Transform the vertex position into projected space.
    pos = mul(pos, model);
    pos = mul(pos, view);
    pos = mul(pos, projection);
    output.pos = pos;

    // Pass through the color without modification.
    output.color = input.color;

    return output;
}
</pre></p><p>The current angle is set to 80 degrees, or 1.3962634 radians. If you run the rendering test application, the result you will get will be similar to this:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013%5B3%5D.jpg"><img title="clip_image013" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image013_thumb.jpg" alt="clip_image013" width="449" height="252" border="0"></a></p><p>Now, let’s look at how shaders are handled on the DirectX side.</p><h4>Shaders in DirectX</h4><p>Open <strong>CubeRenderer.cpp</strong>. This is the source file where internal shaders are read and passed to the device to be executed. Notice one interesting aspect of the process – the shader file contents are being read first and then passed to <strong>m_d3dDevice-&gt;CreateVertexShader</strong>. m_d3dDevice is a pointer to a virtual adapter that can be used to create device-specific resources. <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476524(v=vs.85).aspx">CreateVertexShader</a> creates a vertex shader from an already compiled shader. You can notice it from the fact that the data is read not from the initial <strong>.hlsl</strong> file, but rather from the <strong>.cso (Compiled Shader Object)</strong>:</p><p>auto loadVSTask = DX::ReadDataAsync(&quot;SimpleVertexShader.cso&quot;);</p><p>As with any program, before it is passed onto the execution layer, it has to be compiled first. Visual Studio 2012 comes with a bundled HLSL compiler, <strong>fxc</strong>—the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb232919(v=vs.85).aspx">Effect Compiler Tool</a>. The default behavior for a shader is to be compiled with the .cso file extension in the same output directory as the project, but this can be changed by setting the <strong>Object File Name</strong> in the shader properties:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image015%5B3%5D.jpg"><img title="clip_image015" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image015_thumb.jpg" alt="clip_image015" width="624" height="443" border="0"></a></p><p>You can read more about the shader compilation process <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb509633(v=vs.85).aspx">here</a>.</p><p>Looking back at the sample vertex shader that was created as a part of the project, you will notice that there is a specific input layout set for the incoming object:</p><p><pre class="brush: cpp">
struct VertexShaderInput
{
    float3 pos : POSITION;
    float3 color : COLOR0;
};
</pre></p><p>&nbsp;</p><p>The virtual adapter is not aware of the structure layout. Therefore, the developer needs to explicitly create an internal <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476180(v=vs.85).aspx">D3D11_INPUT_ELEMENT_DESC</a> array that will contain the type of information passed to the shader:</p><p><pre class="brush: cpp">
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
{
    { 
        &quot;POSITION&quot;, 
        0, 
        DXGI_FORMAT_R32G32B32_FLOAT, 
        0, 
        0, 
        D3D11_INPUT_PER_VERTEX_DATA, 
        0 },
    {
        &quot;COLOR&quot;, 
        0, 
        DXGI_FORMAT_R32G32B32_FLOAT, 
        0, 
        12, 
        D3D11_INPUT_PER_VERTEX_DATA, 
        0 },
};
</pre></p><p>&nbsp;</p><p>Once the description is complete, the input needs to be assembled for processing. That’s where <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476512%28v=vs.85%29.aspx">CreateInputLayout</a> comes into play:</p><p><pre class="brush: cpp">
DX::ThrowIfFailed(
    m_d3dDevice-&gt;CreateInputLayout(
        vertexDesc,
        ARRAYSIZE(vertexDesc),
        fileData-&gt;Data,
        fileData-&gt;Length,
        &amp;m_inputLayout
        )
    );
</pre></p><p>&nbsp;</p><p>You are basically passing a shader signature to the input assembler that will perform all the consequent processing. A similar process is applied for the existing pixel shader, with the main difference being the fact that instead of CreateVertexShader, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476513%28v=vs.85%29.aspx">CreatePixelShader</a> is called:</p><h4>Passing Custom Parameters to Shaders</h4><p>Going back to our vertex shader where we performed the rotation relative to the X-axis, you probably noticed that the angle is hard-coded and is applied to each vector in the same way. This is rarely the case, as the angle would normally come from inside the game itself, often responding to internal behavior, such as character movement or action.</p><p>To pass a parameter to the shader, you need to first of all redefine the input structure. Let’s add an angle carrier to the <strong>VertexShaderInput</strong> struct in <strong>SimpleVertexShader.hlsl</strong>:</p><p><pre class="brush: cpp">
struct VertexShaderInput
{
    float3 pos : POSITION;
    float3 color : COLOR0;
    float angle : TRANSFORM0;
};
</pre></p><p>This alone won’t do anything. Go the entry point function (<strong>main</strong>) and make sure that the angle constant is set to <strong>input.angle</strong>:</p><p><pre class="brush: cpp">
const float angle = input.angle;
</pre></p><p>Now the shader is ready, but you also need to let your game know that the vertex shader has a modified input layout. To do this, go to <strong>CubeRenderer.cpp</strong> and find the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476180%28v=vs.85%29.aspx">D3D11_INPUT_ELEMENT_DESC</a> array that defines the input layout for incoming vertex shaders. Simply add an identifying item to the existing array:</p><p><pre class="brush: cpp">
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
{ 
    { &quot;POSITION&quot;, 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 
    { &quot;COLOR&quot;, 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 
    { &quot;TRANSFORM&quot;, 0, DXGI_FORMAT_R32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 } 
};
</pre></p><p>The first parameter is the pre-defined semantic used in the shader. The second parameter defines the input index. After that, use <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx">DXGI_FORMAT_R32_FLOAT</a> to indicate that the value passed will be a standard float. Pay close attention when you specify the input offset. Notice that the two FLOAT3 values, POSITION and COLOR, take 12 bytes each —a float takes 32 bits (4 bytes), and you have a triplet, therefore the offset for TRANSFORM should be 24 bytes (two times 12 bytes from previous indicators).</p><p>Now you need to modify the internal vector descriptors that are being passed to the rendering pipe. In the sample project those are created with the help of the VertexPositionColor class, located in the <strong>CubeRenderer.h</strong>. Add a simple float field to the existing struct, so it looks like this:</p><p><pre class="brush: cpp">
struct VertexPositionColor 
{ 
    DirectX::XMFLOAT3 pos; 
    DirectX::XMFLOAT3 color; 
    float angle; 
};
</pre></p><p>&nbsp;</p><p>In <strong>CubeRenderer.cpp</strong>, find the <strong>cubeVerticles</strong> array. For each created <strong>VertexPositionColor</strong> you are now able to add a third value representing the rotation:</p><p><pre class="brush: cpp">
auto createCubeTask = (createPSTask &amp;&amp; createVSTask).then([this] () { 
    VertexPositionColor cubeVertices[] = 
    { 
        {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f), 1.38f}, 
        {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), 1.38f}, 
        {XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), 1.38f}, 
        {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f), 1.38f}, 
        {XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), 1.38f}, 
        {XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f), 1.38f}, 
        {XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f), 1.38f}, 
        {XMFLOAT3( 0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f), 1.38f}, 
    };
</pre></p><p>&nbsp;</p><p>Now you will be able to pass parameters to the vertex shader without having to manually modify the shader itself.</p><h4>Shaders in FallFury</h4><p>There are several shaders used in FallFury, which must be selected depending on the Direct3D feature level available on the machine. A feature level determines what a video adapter can do in terms of rendering—even though Direct3D is a unified framework, it still heavily relies on how individual graphic cards can perform.</p><p>There are 5 shaders used internally for texture rendering. Specifically, there is a pixel shader, a replication vertex shader, an instancing vertex shader and geometry shaders. This could be familiar if you worked with Microsoft DirectX sprite samples before:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016%5B3%5D.png"><img title="clip_image016" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016_thumb.png" alt="clip_image016" width="337" height="167" border="0"></a></p><p>Given the platform limitations, geometry shaders can only be used on devices supporting Direct3D Feature Level 10. When FallFury detects that the feature level is lower than that, it has to fall back on either the instancing or the replication shaders. Some devices, such as the Microsoft Surface, are at feature level 9.1. Therefore, the replication render technique must be enforced.</p><p>Following the <a href="http://code.msdn.microsoft.com/windowsapps/Direct3D-sprite-sample-97ae6262">Microsoft DirectX Sprite Sample</a>, it is fairly easy to simply select the correct render technique once the feature level is detected with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff476528%28v=vs.85%29.aspx">GetFeatureLevel</a>:</p><p><pre class="brush: cpp">
auto featureLevel = m_d3dDevice-&gt;GetFeatureLevel(); 
if (featureLevel &gt;= D3D_FEATURE_LEVEL_10_0) 
{ 
    m_technique = RenderTechnique::GeometryShader; 
} 
else if (featureLevel &gt;= D3D_FEATURE_LEVEL_9_3) 
{ 
    m_technique = RenderTechnique::Instancing; 
} 
else 
{ 
    m_technique = RenderTechnique::Replication; 
    if (capacity &gt; static_cast&lt;int&gt;(Parameters::MaximumCapacityCompatible)) 
    { 
        // The index buffer format for feature-level 9.1 devices may only be 16 bits. 
        // With 4 vertices per sprite, this allows a maximum of (1 &lt;&lt; 16) / 4 sprites. 
        throw ref new Platform::InvalidArgumentException(); 
    } 
}
</pre></p><p>&nbsp;</p><p>Depending on the selected render technique, which is determined on application startup, the proper input layout is selected for each shader and is used to control the rendering pipe.</p><p>Different graphic adapters also support different <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff471356%28v=vs.85%29.aspx">shader models</a>. You need to account for those, and before running the application, the HLSL compiler will take on the task of determining whether a proper shader component is supported by the given model. In the shader properties, make sure that you specify the used shader model, as well as the type of the shader:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image018%5B3%5D-1.jpg"><img title="clip_image018" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image018_thumb-1.jpg" alt="clip_image018" width="624" height="443" border="0"></a></p><p>Without this, you are bound to experience compile time errors that will prevent you from launching the application or deploying it to different devices.</p><h4>Conclusion</h4><p>Shaders are not an easy subject. I highly recommend reading <a href="http://http.developer.nvidia.com/CgTutorial/cg_tutorial_frontmatter.html">The Cg Tutorial</a>, published online for free by nVidia. Even though it describes the Cg shader language, it is virtually identical to HLSL and you will not have any problems using the practices you learned there in building HLSL shaders.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:e11fdf9075a54e749835a13f017319dd">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders</comments>
      <itunes:summary>Introduction to ShadersFallFury not only relies on standard C&amp;#43;&amp;#43;/C# and XAML code, but also on shaders. This article is intended for developers who are not aware of what shaders are and want to know how to use them in their projects. I will talk about creating shaders, as well as the shaders used in my project. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-2-Shaders.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Code on GPUIn simple terms, shaders are small programs that are executed on the Graphical Processing Unit (GPU) instead of the Central Processing Unit (CPU). In recent years, we’ve seen a major spike in the capabilities of graphic devices, allowing hardware manufacturers to design an execution layer tied to the GPU, therefore being able to target device-specific manipulations to a highly optimized unit. Shaders are not used for simple calculations, but rather for image processing. For example, a shader can be used to adjust image lighting or colors. Modern GPUs give access to the rendering pipeline that allows developers to execute arbitrary image processing code. This is a step forward from a fixed-function pipeline that was present in older GPUs, where image processing tasks were integrated into the hardware unit and were only able to perform a limited set of actions, such as transforms. Unlike the rendering pipeline, the fixed-function pipeline was not programmable, therefore the developers were often tied to the hardware they used for offering specific game effects, in some cases having to resort to software-based adjustments. Types of ShadersThere are different types of image manipulations that can be performed on a given input, and so there are different types of shaders designed to handle that. Currently, we can highlight three main shader types: Vertex shaders – because what the user sees on the screen is not really three-dimensional, b</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders</link>
      <pubDate>Wed, 23 Jan 2013 23:57:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/0419/408466c0-5dee-4616-b76d-3c5e824a0419/FallFuryPart2_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-2-Shaders/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>DirectX</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Fall Fury: Part 1 - Introduction</title>
      <description><![CDATA[<p>In late May, I arrived in Redmond to work as an intern on the Channel9 team. I had the freedom to choose what I was going to work on, so I decided to challenge myself and work outside my comfort zone, utilizing less C# and managed code and more C&#43;&#43; and DirectX. To do so, I decided to highlight the capabilities of Windows 8—that’s how FallFury was born.</p><p>FallFury is a 2D platformer in which the player controls a falling bear, trying to avoid obstacles, dodge missiles, and destroy monsters as the bear falls. The project incorporates several of the new Windows 8 APIs, including the accelerometer and touch as well as integrations with core OS capabilities such as settings and share charms. Additionally, the project leverages the most exacting addition to the Visual Studio development environment—hybrid application development with XAML, C&#43;&#43;, and DirectX.</p><p>Check out the video for this article at <a href="http://channel9.msdn.com/Series/FallFury/Part-1-Introduction">http://channel9.msdn.com/Series/FallFury/Part-1-Introduction</a>.&nbsp; For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>.</p><h4>Design &amp; Idea</h4><p>From the outset, Rick Barraza and I decided that since our target audience was composed of both kids and adults, the main character had to be familiar to both groups. Teddy bears turned out to be the best choice. Rick spent a day creating tens of potential bear drawings—out of which I had to choose one:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B5%5D%5B2%5D.jpg"><img title="clip_image002[5]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B5%5D_thumb.jpg" alt="clip_image002[5]" width="437" height="328" border="0"></a> <a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B5%5D%5B2%5D.jpg"><img title="clip_image004[5]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B5%5D_thumb.jpg" alt="clip_image004[5]" width="247" height="329" border="0"></a></p><p>As the bear’s fall progresses, the character encounters a variety of obstacles dependent on the level type and complexity. Those obstacles should of course be avoided, so as the user tilts the device, the character in the game moves in the associated direction.</p><p>The design of the project took a week, and during this time the following items were determined and conceptualized. Considerations for both tablet and desktop environments directed our decisions:</p><p>· The main character layout.</p><p>· The way the game progresses as the character falls down.</p><p>· How the user interacts with the game in a wide variety of possible scenarios.</p><p>· What the game screens look like.</p><p>· What the menu system interaction looks like.</p><p>· How the game looks in different screen modes and on different device types.</p><p>· Some of the bonuses that the main character can pick up during free fall.</p><p>· What happens when the user progresses through the game and iterates through levels.</p><p>· What is shared and how this is accomplished.</p><p>As the game ideas were outlined, Arturo Toledo, the designer behind <a href="http://ux.artu.tv/">ux.artu.tv</a>, was brought on to create the game assets. Then the core design decisions were made and we jumped into the development process.</p><h4>Beginning the development</h4><p>You will need to download and install <a href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products">Microsoft Visual Studio 2012 Express for Windows 8</a> in order to be able to follow the steps that I am describing in this series. The development has to be done on Windows 8, because the end result is a Windows Store application that relies on Windows 8 APIs. Though specific hardware is not required, both ARM and x86 devices will work well, so whether you have a Microsoft Surface RT or Samsung Series 7 slate, you will be able to test the code when you have the opportunity.</p><p>To get started, open Visual Studio 2012 and select the C&#43;&#43; project types. You will notice that there are several options you can choose from. You want to create a Windows Store application, so choose the appropriate category. Windows Store applications run in a sandbox, outside the boundaries of the standard .NET runtime.</p><p>Next, select the <strong>Direct2D (XAML)</strong> app type from the project list. This is a new application type <a href="http://blogs.msdn.com/b/windowsappdev/archive/2012/03/15/combining-xaml-and-directx.aspx">introduced in Visual Studio 2012</a> that allows developers to combine native DirectX graphics with XAML overlays. Do not be confused by the fact that there is a Direct2D in the name—you can still invoke DirectX capabilities supported in the WinRT sandbox:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B6%5D%5B2%5D.jpg"><img title="clip_image006[6]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image006%5B6%5D_thumb.jpg" alt="clip_image006[6]" width="617" height="376" border="0"></a></p><p>At this point you might be wondering, why choose a hybrid application instead of a fully-native project? The reason behind this decision is that is allows the developer to focus more on fine-tuning the gameplay instead of creating the UI core in pure DirectX. Because XAML is a part of the game, we can create dynamic UI layouts for the HUD, settings charm and menus without touching the graphical backbone. It is possible to do the same directly through DirectX and was a perfect approach for FallFury, considering the time constraints and the fact that I needed minimal UI overlays. Most of the graphics were already processed through the DirectX pipeline, so I did not have to invest significant resources and time into designing low-level structures for the interactivity layer.</p><p>FallFury uses XAML for the following:</p><ul><li><strong>Menus</strong> – depending on the screen, the user is able to trigger a number of actions. For example, when the game starts, the user might select the New Game option or decide to take a look at the About screen. In Paused mode, the menu is used to resume the game, adjust settings, or possibly skip a level. </li><li><strong>Game HUD</strong> (score indicator, pick-up indicator, health indicator) – during the gameplay, the user is interested in keeping track of where the character is and what is the state of it. The game HUD is shown in active game mode. </li><li><strong>Settings charm extensions</strong> – the way the Settings charm works, the OS provides the core harness to hook to the Settings popup. Once shown, it is up to the developer to provide a multitude of options that customize the application behavior; any additional popups shown on selection should be designed individually in XAML. </li><li><strong>User notification</strong> – when something happens that can potentially affect the gameplay, the user should be alerted. The core framework provides the capabilities to use a MessageDialog, but in some cases it might not be enough. For example, if new levels are available for download, the user might want to check those out in a custom popup including full previews rather than just text. </li></ul><p>When you create the project, a default infrastructure that prints text on the screen—both through Direct2D and XAML—is available. Direct2D is a subset of DirectX APIs and facilitates hardware-accelerated 2D graphics processing. It is used to create basic geometry elements and text. Since I am here working mostly with XAML, I am not going to cover Direct2D in-depth in this article:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B5%5D%5B2%5D.jpg"><img title="clip_image008[5]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image008%5B5%5D_thumb.jpg" alt="clip_image008[5]" width="640" height="345" border="0"></a></p><p>I will go into more details regarding the XAML and DirectX interaction model later in the series, but for now, take a look at which parts of the project you have available. First and foremost, you probably notice the combination of both C&#43;&#43; source and header files and <strong>DirectXPage.xaml</strong>. Starting with Visual Studio 2012, you are now able to <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465045.aspx">create XAML applications in C&#43;&#43;</a>. So even if you are an experienced C&#43;&#43; developer who never worked with the Extensible Application Markup Language, you can create the product core in your familiar environment and either import existing XAML structures or delegate the XAML writing to a designer.</p><p>If you open the XAML page, you will notice one significant change that you haven’t experienced in standard XAML applications, such as WPF or Silverlight for Windows Phone:</p><p><pre class="brush: xml">
&lt;SwapChainBackgroundPanel x:Name=&quot;SwapChainPanel&quot; PointerMoved=&quot;OnPointerMoved&quot; PointerReleased=&quot;OnPointerReleased&quot;&gt;
    &lt;TextBlock x:Name=&quot;SimpleTextBlock&quot; HorizontalAlignment=&quot;Center&quot; FontSize=&quot;42&quot; Height=&quot;72&quot; Text=&quot;Hello, XAML!&quot; Margin=&quot;0,0,0,50&quot;/&gt;
&lt;/SwapChainBackgroundPanel&gt;
</pre></p><p>A <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.swapchainbackgroundpanel.aspx">SwapChainBackgroundPanel</a> is a component that lets the developer overlay XAML on top of the core DirectX-based experience. Look, for example, at the FallFury main menu as the game runs in landscape mode:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B6%5D%5B2%5D.jpg"><img title="clip_image010[6]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image010%5B6%5D_thumb.jpg" alt="clip_image010[6]" width="624" height="351" border="0"></a></p><p>The menu buttons, the label and the side curtains are designed and rendered entirely in XAML. The clouds in the background, as well as the teddy bear, are rendered directly through the DirectX stack. The end-user does not notice any difference in the way these elements interact or are displayed. From a development perspective, however, there are several conditions that must be met.</p><p>There can only be one instance of SwapChainBackgroundPanel per app. Therefore, you can have only one overlaid XAML controls set. This does not mean that you can’t have multiple controls, but it implies that to do so you have to implement a control management flow that handles content adaptation. For example, if I invoke the pause state in the game, I don’t show the HUD but rather the screen-specific controls that let me resume or abandon the game and the PAUSE label. This switch needs to be handled on both the DirectX and XAML because a state change affects what is shown on the screen and what behaviors are tracked. As you will see through this series, this is not too hard to implement with a helper class that will store the global game state, that can be accessed from anywhere in the game.</p><p>When using SwapChainBackgroundPanel, remember that XAML is in all cases overlaid on top of the DirectX renders. So, no matter what controls you are using, those will always be placed on top of what DirectX shows to the user. For more details about how DirectX and XAML interoperate, check out <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh825871.aspx">this MSDN article</a>.</p><h4>Assets for the game</h4><p>As with any other game, there is not only code involved in production—there are also sound and graphical assets that create a unique experience for the user. FallFury includes a wide variety of graphical assets designed by <a href="http://ux.artu.tv/">Toledo Design</a> as well as audio created by <a href="http://davidwallimann.com/">David Walliman</a>.</p><p>It is important that all graphical resource requirements are established at the very beginning of development. As I mentioned in the Design section of this article, I had to put together a list of all the game screens, power-ups, obstacles, backgrounds, character states and possible particles that were generated from a texture. That way, when the designer started creating the assets, all components blended together well and their styles were compatible with the vision of the game.</p><p>While working on the assets, Arturo Toledo created multiple variations of the same set up that showed how assets integrate in different game conditions:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B5%5D%5B2%5D.jpg"><img title="clip_image012[5]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B5%5D_thumb.jpg" alt="clip_image012[5]" width="460" height="480" border="0"></a></p><p>As you follow this series, you will not have to create your own game assets—we at Coding4Fun decided to provide all graphical and audio assets, which you can download at <a href="http://fallfury.codeplex.com/">http://fallfury.codeplex.com/</a>.&nbsp; We not only provided you with the final PNG and DDS files, but also with the raw assets that can be used in Microsoft Expression Design and Adobe Illustrator. Let’s take a look at what is in the package.</p><p>You will notice that the project Assets folder is split in several subfolders. All these assets are used mostly in the XAML layer or in game conditions where texture/sound processing is not necessary. There is also an additional asset folder I will discuss later.</p><ul><li><strong>Backgrounds</strong> –the level backgrounds, such as the blue, purple or red sky, as well as the overlays, such as clouds that move simultaneously with the backgrounds. Each background/overlay combination is assigned to a specific level type. </li><li><strong>Bear</strong> – some of the bear elements that are displayed at different times in the game, such as when the game is over or when the player wins the entire level set. </li><li><strong>HUD</strong> – basic elements that are displayed during the game. </li><li><strong>Icons</strong> – the application icons, in a variety of sizes, required for a Windows Store application. </li><li><strong>Medals</strong> – winning players are awarded a medal. It can be golden, silver, or bronze. </li><li><strong>Misc</strong> – you get some branding elements as well as some graphics that are used in combination with other game items, such as particles. </li><li><strong>Monsters</strong> – monsters are used in the “How To” part of the game. </li><li><strong>Music</strong> – the long tracks used in different levels and screens. </li><li><strong>Sounds</strong> – short sound clips used when different game behaviors in the game are triggered. For example, when the bear gets hit, he lets out a brief cry. </li></ul><p>All graphical assets mentioned here are PNG resources. The way I structured the game, some elements are larger than the others and I needed to take some measures to cut down on the package size. PNGs are fairly well-sized without much quality loss compared to raw images. At the beginning of the development process, all graphics were stored in DDS files.</p><p><a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff553839(v=vs.85).aspx">DirectDraw Surface</a>, or DDS, is a file format developed by Microsoft that helps developers optimize some of the graphics by avoiding re-compression performance loss. One of the benefits of using DDS files is the fact that whenever they are processed by the GPU, the amount of memory taken by them is the same as the file size of the DDS file itself. Usually, for 2D games the compression-based performance loss is not necessarily noticeable. For PNG files used on the DirectX stack, resources are allocated to decompress the texture. Not so for DDS files.</p><p>Depending on the case, DDS files can be generated on the fly. FallFury preserves relatively small textures in DDS format and larger ones, such as backgrounds, in PNG. It’s the best of both worlds. DDS files can be generated by a tool bundled with the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=6812">DirectX SDK</a> called <strong>dxtex</strong> (usually located in <em>C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x64</em>):</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B5%5D%5B2%5D.jpg"><img title="clip_image014[5]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B5%5D_thumb.jpg" alt="clip_image014[5]" width="640" height="328" border="0"></a></p><p>There is also <strong>texconv</strong> that allows you to create DDS components from the command line, but we’ll explore that later in the series.</p><p>All DDS assets are located in the DDS folder in the solution. All that’s there are assets related to levels, such as obstacles, and assets related to character behavior, such as bear states and used weapons and powerups.</p><p>Unlike graphic assets that can be mocked from the very start, audio assets are a bit harder to come up with, mainly because at that point you need to be sure what the game will be like at the end. Music and effects should go together with the overall game feel. There are two types of audio components in FallFury—the music and the action-based sound effects. Music is played constantly, whether in the game or on a game screen such as the main menu, unless disabled by the user.</p><p>The way the audio engine works in FallFury, files are handled differently depending on where in the game they are used. All music is stored in MP3 files and the short sound effects are stored in uncompressed WAV files.</p><p>As a part of the new project that you are creating, replicate the folder structure for the Assets and DDS folders and add them to the solution. The way C&#43;&#43; project references work, you might want to switch to the “Show All Files” mode in the Solution Explorer:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image015%5B5%5D%5B2%5D.png"><img title="clip_image015[5]" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image015%5B5%5D_thumb.png" alt="clip_image015[5]" width="341" height="99" border="0"></a></p><p>Then, simply copy the folders to the solution folder itself. That way you will have all these resources as a part of the project itself and not just links to external files.</p><h4>Source Control</h4><p>It’s a really good idea to use source control. There are multiple options available at no cost, such as <a href="http://www.codeplex.com/">CodePlex</a>, <a href="https://www.assembla.com/">Assembla</a>, and <a href="http://tfs.visualstudio.com/">Team Foundation Service</a>. You need source control for multiple reasons. The most important reason of them all, however, is that code will break. There were multiple situations where I changed parts of the project and all of a sudden some components stopped working. With the project hooked to a source control system, all I needed was to do a quick rollback to the previous check-in and I was good to go.</p><p>A good practice I learned from <a href="http://twitter.com/ClintRutkas">Clint Rutkas</a> is performing atomic check-ins. When something goes wrong, it is much easier to go back to the check-in where only 20 or 30 code lines were modified from what is currently in the stack, compared to going back to the solution where you will be missing two or more entire source files.</p><h4>Modular Design &amp; Prototyping</h4><p>As you are following this project creation from scratch, notice how the entire code base is modular and interchangeable. If I decide to create a new game screen, I can do so easily by inheriting from an existing base class that provides the basic harness. If I want to replace a character model, I can do so by modifying a single class without breaking the entire interaction model.</p><p>Prototyping is also a big part of FallFury and it is key that no time is wasted working on features that will have to be entirely replaced or re-written. A good example to this scenario happened just as I started writing the project code. I noticed that the Settings charm required some XAML work for secondary popups that extended from the OS-invoked layer. As I was working on a pure DirectX application, I had to create the XAML in code-behind and that was one of the experiences that could’ve been avoided in a hybrid application. During the prototyping stage it is easy to spot potential integration problems and later change parts of the project to work better together. It is much more complicated to replace project components when the core is wired-in than when you have small parts that independently show how a part of the game works.</p><h4>Hardware</h4><p>As you are about to start writing large amounts of code, you are probably wondering whether actual hardware is needed to test the application. The way FallFury was designed, you will be able to run it on any Windows 8 compatible machine, whether a desktop computer or a tablet. If the game is being run on the desktop, I assume that you probably do not have access to an accelerometer or a touch display. If you are running the game on the tablet, you probably do not have a physical keyboard constantly attached to it. These facts ultimately affect how you experience the game itself. From a development perspective, it is important to have multiple types of target hardware available, because the game might behave differently depending on the device configuration. But it is not required to follow this article series. As long as you have a Windows 8 machine, you are good to go.</p><h4>Conclusion</h4><p>Now onto 11 more articles on how to build Fall Fury!</p><p>&nbsp;</p><p><strong>For a complete, offline version of this series, you may <a href="http://media.ch9.ms/coding4fun/fallfury/FallFury.pdf">download a nicely formatted PDF of all the articles</a>!</strong></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:9e270d362db647ffb3eba13f016b83d8">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction</comments>
      <itunes:summary>In late May, I arrived in Redmond to work as an intern on the Channel9 team. I had the freedom to choose what I was going to work on, so I decided to challenge myself and work outside my comfort zone, utilizing less C# and managed code and more C&amp;#43;&amp;#43; and DirectX. To do so, I decided to highlight the capabilities of Windows 8—that’s how FallFury was born. FallFury is a 2D platformer in which the player controls a falling bear, trying to avoid obstacles, dodge missiles, and destroy monsters as the bear falls. The project incorporates several of the new Windows 8 APIs, including the accelerometer and touch as well as integrations with core OS capabilities such as settings and share charms. Additionally, the project leverages the most exacting addition to the Visual Studio development environment—hybrid application development with XAML, C&amp;#43;&amp;#43;, and DirectX. Check out the video for this article at http://channel9.msdn.com/Series/FallFury/Part-1-Introduction.&amp;nbsp; For a complete, offline version of this series, you may download a nicely formatted PDF of all the articles. Design &amp;amp; IdeaFrom the outset, Rick Barraza and I decided that since our target audience was composed of both kids and adults, the main character had to be familiar to both groups. Teddy bears turned out to be the best choice. Rick spent a day creating tens of potential bear drawings—out of which I had to choose one:   As the bear’s fall progresses, the character encounters a variety of obstacles dependent on the level type and complexity. Those obstacles should of course be avoided, so as the user tilts the device, the character in the game moves in the associated direction. The design of the project took a week, and during this time the following items were determined and conceptualized. Considerations for both tablet and desktop environments directed our decisions: &#183; The main character layout. &#183; The way the game progresses as the character falls down. &#183; How the user interacts with the g</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction</link>
      <pubDate>Wed, 23 Jan 2013 23:56:55 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_220.jpg" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/46d7/a0462890-d8c4-4c41-9cf5-ec53e9e946d7/FallFuryPart1_512.jpg" height="289" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Den Delimarsky, Rick Barraza</itunes:author>
      <slash:comments>9</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Fall-Fury-Part-1-Introduction/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>Windows Store App</category>
    </item>
  <item>
      <title>Maelstrom: An Overview</title>
      <description><![CDATA[<p>For <a href="http://buildwindows.com/">//build/ 2012</a>, we wanted to showcase what Windows 8 can offer developers.&nbsp; There are a lot of projects showing off great things like contracts and Live Tiles, but we wanted to show off some of the lesser known features.&nbsp; This project focuses on one of those: stereoscopic 3D with DirectX 11.1.</p><p>Prior to DirectX 11.1, stereoscopic 3D required specific hardware and a custom API written for that hardware.&nbsp; With DX11.1, stereoscopic 3D has been &quot;democratized.&quot;&nbsp; Any GPU that supports DirectX 11.1 can be connected to any device which supports stereoscopic 3D, be it a projector, an LCD TV, or anything else.&nbsp; Plug it in and DirectX does the rest.</p><p>From the software side of things, any DX11.1 application can determine if the connected display supports stereoscopic 3D, and choose to render itself separately for the player's left and right eye.</p><p>To showcase this feature, we decided to build a very simple game that would give the illusion of depth, but be easy to explain and play.&nbsp; What's easier than <a href="http://en.wikipedia.org/wiki/Pong">Pong</a>?&nbsp; So, we built the world's most over-engineered game of 3D Pong named Maelstrom.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/WP_000414%5B6%5D.jpg"><img title="WP_000414" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/WP_000414_thumb%5B3%5D.jpg" alt="WP_000414" width="640" height="480" border="0"></a></p><h2>Software</h2><p>Each player setup consists of two applications: the DirectX 11.1 game written in C&#43;&#43;, and the touch-screen controller written in C#/XAML.&nbsp; Both are Windows Store applications.&nbsp; Since this is a two player game, there are two instances of each application running, one per player.&nbsp; All for applications are networked together using <strong>StreamSocket</strong>s from the Windows Runtime.&nbsp; The two controllers and player two's DirectX game connect to player one's DirectX game, which acts as the &quot;master&quot;.&nbsp; Controller input is sent here, and, once the ball and paddle positions are calculated, the data is drawn for player one and sent to player two which draws the world from the other player's perspective.</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B3%5D-2.png" alt="image" width="640" height="269" border="0"></p><h3>Direct3D Application</h3><h2>Getting Started with stereoscopic DirectX11, C&#43;&#43;, and XAML</h2><p>If you have never worked with DirectX before, it can be a little overwhelming at first. And even if you have worked with it some in the past, targeting the new Windows 8 ecosystem, along with C&#43;&#43; and XAML have added some additional changes in how you may have designed your solution previously.</p><p>Fortunately, the <a href="http://dev.windows.com/">Windows Dev Center</a> for Windows Store Apps has some great samples to get you started, and we took full advantage of them to get to speed. For a great, simple example of how to leverage the new stereoscopic feature in Direct3D 11.1, we started with <a href="http://code.msdn.microsoft.com/windowsapps/Direct3D-111-Simple-Stereo-9b2b61aa/view/SourceCode#content">Direct3D Stereoscopic Sample</a> which shows the basic adjustments to the Render loop for toggling your virtual cameras. However, to see a great example of a simple game structure that also leverages stereoscopic rendering where available, the tutorial found at <a href="http://msdn.microsoft.com/en-us/library/windows/apps/Hh780567.aspx">Walkthrough: a simple Windows Store game with DirectX</a> is invaluable. Further in this article, we will dive deeper into the specifics of stereoscopic rendering in our game.</p><p>One thing to note, if you follow the link in the above Walkthrough to the original project, it will take you to a C&#43;&#43; only implementation of the game. Now, of course, all the DirectX game objects such as the paddle, puck and walls are all rendered using D3D. However, for HUD (Heads up Display) elements, this C&#43;&#43; only sample also uses DirectX exclusively. If you are coming from a managed code background, this will definitely seem like unnecessary overhead. That is because this C&#43;&#43; only sample was created after last year's BUILD conference in 2011 and C&#43;&#43; and DirectX still did not play well with XAML.</p><p>However, a few months later, the ability to nest DirectX content in a XAML project became available for true hybrid style solutions (see the article <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh825871.aspx">DirectX and XAML interop - Windows Store apps using C&#43;&#43; and DirectX</a> for more information). After this feature was added, the simple Shooter Game referenced above had its HUD logic rewritten in XAML and posted up to Dev Center as <a href="http://code.msdn.microsoft.com/windowsapps/Metro-style-DirectX-18f98448#content">XAML DirectX 3D shooting game sample</a>, which shows both stereoscopic support, a simple Game Engine structure in C&#43;&#43; and XAML integration. At this point, we had all the starter code we needed to start writing our own game.</p><h2>Game Engine</h2><p>We modified the base sample to accommodate our needs.&nbsp; We created specific <strong>GameObject</strong>s, such as <strong>Paddle</strong>, <strong>Puck</strong>, etc. to add the behaviors we needed.&nbsp; We also added an <strong>Update</strong> and <strong>Render</strong> method to the base <strong>GameObject</strong> so that, for every frame, we could do any calculations required, and then draw the object to the screen.&nbsp; This is very similar to how XNA sets up its game engine.</p><h2>Game Constants</h2><p>Because we were tweaking a variety of values like colors, sizes, camera locations, etc., we created a <strong>GameConstants.h</strong> header file which contains nothing but these types of values in a single location.&nbsp; This made it very easy for us to quickly try out various tweaks and see the results on the next run.&nbsp; Using namespaces helped keep the code a bit more manageable here as well.&nbsp; Here’s a quick snippet of that file:</p><p><pre class="brush: csharp">
namespace GameConstants
{
    // bounds of the arena
    static const DirectX::XMFLOAT3 MinBound    = DirectX::XMFLOAT3( 0.0f,  0.0f,  0.0f);
    static const DirectX::XMFLOAT3 MaxBound    = DirectX::XMFLOAT3(19.0f, 10.0f, 90.0f);

    // game camera &quot;look at&quot; points
    static const DirectX::XMFLOAT3 LookAtP1    = DirectX::XMFLOAT3(9.5f, 5.0f, 90.0f);
    static const DirectX::XMFLOAT3 LookAtP2    = DirectX::XMFLOAT3(9.5f, 5.0f,  0.0f);

    // Waiting Room camera positions
    static const DirectX::XMFLOAT3 WaitingEyeP1                = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MaxBound.z - 12.0f);
    static const DirectX::XMFLOAT3 WaitingEyeP2                = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MinBound.z &#43; 12.0f);
    static const DirectX::XMFLOAT3 WaitingEyeMjpegStation    = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MinBound.z &#43; 9.6f);

    // game camera eye position
    static const DirectX::XMFLOAT3 EyeP1        = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MinBound.z - 6.0f);
    static const DirectX::XMFLOAT3 EyeP2        = DirectX::XMFLOAT3(GameConstants::MaxBound.x/2, GameConstants::MaxBound.y/2, GameConstants::MaxBound.z &#43; 6.0f);

    static const float Paddle2Position    = MaxBound.z - 5.0f;

    namespace PaddlePower
    {
        // power level to light paddle at maximum color
        static const float Max                    = 9.0f;

        // max paddle power color...each component will be multiplied by power factor
        static const DirectX::XMFLOAT4 Color    = DirectX::XMFLOAT4(0.2f, 0.4f, 0.7f, 0.5f);
    
        // factor to multiply mesh percentage based on power
        static const float MeshPercent            = 1.2f;
    };
    
    // time to cycle powerups
    namespace Powerup
    {
        namespace Split
        {
            static const float Time                        = 10.0f;
            static const float NumTiles                    = 4;
            static const DirectX::XMFLOAT4 TileColor    = DirectX::XMFLOAT4(0.1f, 0.4f, 1.0f, 1.0f);
            static const float TileFadeUp                = 0.20f;
            static const float TileDuration                = 2.10f;
            static const float TileFadeDown                = 0.20f;
            static const float TileMeshPercent            = 2.0f;
            static const float TileDiffusePercent        = 2.0f;
        };
    };
}
</pre></p><h2>Stereoscopic 3D</h2><p>Direct3D must be initialized properly to support stereoscopic displays.&nbsp; When the swap chains are created, an additional render target is required, such that one render target is for the left eye, and one render target is for the right eye.&nbsp; Direct3D will let you know if a stereoscopic display is available, so you can create the swap chain and render targets appropriately.</p><p>With those in place, it’s simply a matter of rendering your scene twice, once per eye…that is, once per render target.</p><p>For our game this was very simple.&nbsp; Our in-game camera contains two projection matrices, one representing the view from the left eye, and one from the right eye.&nbsp; These are calculated when the projection parameters are set.</p><p><pre class="brush: cpp">
void Camera::SetProjParams(
    _In_ float fieldOfView,
    _In_ float aspectRatio,
    _In_ float nearPlane,
    _In_ float farPlane
    )
{
    // Set attributes for the projection matrix.
    m_fieldOfView = fieldOfView;
    m_aspectRatio = aspectRatio;
    m_nearPlane = nearPlane;
    m_farPlane = farPlane;
    XMStoreFloat4x4(
        &amp;m_projectionMatrix,
        XMMatrixPerspectiveFovLH(
            m_fieldOfView,
            m_aspectRatio,
            m_nearPlane,
            m_farPlane
            )
        );

    STEREO_PARAMETERS* stereoParams = nullptr;
    // Update the projection matrix.
    XMStoreFloat4x4(
        &amp;m_projectionMatrixLeft,
        MatrixStereoProjectionFovLH(
            stereoParams,
            STEREO_CHANNEL::LEFT,
            m_fieldOfView,
            m_aspectRatio,
            m_nearPlane,
            m_farPlane,
            STEREO_MODE::NORMAL
            )
        );

    XMStoreFloat4x4(
        &amp;m_projectionMatrixRight,
        MatrixStereoProjectionFovLH(
            stereoParams,
            STEREO_CHANNEL::RIGHT,
            m_fieldOfView,
            m_aspectRatio,
            m_nearPlane,
            m_farPlane,
            STEREO_MODE::NORMAL
            )
        );
}
</pre></p><p>Depending on which eye we are rendering, we grab the appropriate projection matrix and pass it down to the vertex shader, so the final scene is rendered offset for the proper eye.</p><h2>Collision Detection</h2><p>If you are just starting to move into 3D modeling and programming, one of the trickier aspects of your game can be collision detection and response. Maelstrom uses primitives for all of the game elements, so our collision code was able to be a bit more straightforward compared to complex mesh collisions, but understanding a few core math concepts is still critical to grasp what the code is doing.</p><p>Fortunately, DirectX provides us with an <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee415571%28v=vs.85%29.aspx">DirectX Math Library</a> that is able to do the serious heavy lifting, so the main complexity comes from framing the problem and learning how to apply the library.</p><p>For example, In our situation we had up to three very fast moving spheres and needed to check for wall collisions and then handle to appropriate bounce, since some of the walls would also be angled. In a 2D game, a collision detection between a sphere and an axis line is very easy. If the distance between a circle and the line is less than or equal to the radius of the sphere, they are touching. On every frame, you move your circle based on its velocity and do your collision test again. But even here, your solution may not be that easy for two reasons.</p><p>First, what if the line is angled and not lying flat on the X or Y axis? You have to find the point on the line based on the line's angle that is closest to the sphere to do your distance calculations. And if you then want it to bounce, you have to rotate the velocity of the circle by the line's angle, calculate your bounce, and then rotate back. And that's just rotated walls in 2D. When you move up to 3D, you have to take into account the surface normal&nbsp; (which way the 3D plane is facing) in your calculations.</p><p>The second complexity that we needed to account for and which pops up in either 2D or 3D collision detection is travel between frames. In other words, if your ball is travelling very fast, it may have completely travelled through your collision boundary in between frames and you wouldn't notice it if you are only doing a distance / overlap check as outlined above. In our case, the pucks had the ability of travelling very fast with a speed boost, so we needed a more robust solution. Therefore, instead of implementing a simple sphere plane intersection test, we needed to create a line of motion that represented where the ball ended on the previous frame and where it currently is after it's new velocity is added to it's position. That line then needs to first be tested to see if it crosses a WallTile. If it does cross, then we know an collision has occurred between frames. We then solve for the time (t) between frames the Sphere would have first made contact to know the exact point of impact and calculate the appropriate &quot;bounce off&quot; direction.</p><p>The final code for a puck (or moving sphere) and wallTile collision test looks like this:</p><p><pre class="brush: cpp">
bool GameEngine::CheckWallCollision(Puck^ puck)
{
    bool isIntersect = false;
    bool wallCollision = false;

    for(unsigned int i = 0; i &lt; m_environmentCollisionWalls.size(); i&#43;&#43;)
    {
        WallTile^ wall = m_environmentCollisionWalls[i];
        float radius = puck-&gt;Radius();
        float signedRadius = puck-&gt;Radius();
        float contactTime = 0.0f;
        XMVECTOR contactPlanePoint = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
        XMVECTOR contactPuckPosition = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

        bool intersectsPlane = false;

        // Determine the velocity of this tick by subtracting the previous position from the proposed current position.
        // in the previous update() cycle, puck-&gt;Position() = puck-&gt;OldPosition() &#43; ( puck-&gt;velocity * timerDelta ).
        // Therefore, this calculated velocity for the current frame movement differs from the stored velocity
        // since the stored velocity is independent of each game tick's timerDelta.
        XMVECTOR puckVectorVelocity = puck-&gt;VectorPosition() - puck-&gt;OldVectorPosition();
        float D = XMVectorGetX( XMVector3Dot( wall-&gt;VectorNormal(), wall-&gt;VectorPosition() ) );

        // Determine the distance of the puck to the plane of the wall.
        float dist = XMVectorGetX( XMVector3Dot(wall-&gt;VectorNormal(), puck-&gt;OldVectorPosition() )) - D;
        signedRadius = dist &gt; 0 ? radius : -radius;

        // if the distance of the puck to the plane is already less than the radius, the oldPosition() was intersecting already
        if ( fabs(dist) &lt; radius )
        {
            // The sphere is touching the plane.
            intersectsPlane = true;
            contactTime = 0.0f;
            contactPuckPosition = puck-&gt;OldVectorPosition();
            contactPlanePoint = puck-&gt;OldVectorPosition() &#43; wall-&gt;VectorNormal()*XMVectorSet(signedRadius,signedRadius,signedRadius,1.0f);
        }
        else
        {
            // See if the time it would take to cross the plane from the oldPosition() with the current velocity falls within this game tick.
            // puckVelocityNormal is the amount of force from the velocity exerted directly toward the plane.
            float puckVelocityNormal = XMVectorGetX(XMVector3Dot(wall-&gt;VectorNormal(), puckVectorVelocity ));
            // if the puckvVelocityNormal times the distance is less than zero, a plane intersection will occur
            if ( puckVelocityNormal * dist &lt; 0.0f )
            {
                // determine the contactTime, taking into account the shell of the sphere ( position() &#43; radius )
                // is what will make contact, not the position alone.
                contactTime =  (signedRadius - dist) / puckVelocityNormal;
                // if the contact time is bewteen zero and one, the intersection has occured bewteen oldPosition() and position()
                if ( contactTime &gt; 0.0f &amp;&amp; contactTime &lt; 1.0f )
                {
                    intersectsPlane = true;
                    // this is the position of the puck when its shell makes contact on the plane
                    contactPuckPosition = puck-&gt;OldVectorPosition() &#43; XMVectorScale(puckVectorVelocity, contactTime);
                    // this is the position on the plane where the shell touches.
                    contactPlanePoint = contactPuckPosition - XMVectorScale(wall-&gt;VectorNormal(), signedRadius);
                }
            }
        }

        // If the puck has contacted the wall plane, determine if the point of contact falls within the wall boundary for true contact.
        if (intersectsPlane)
        {
            float Kr = 1.0f; // Kr is the coefficient of restitution. At 1.0, we have a totally elastic bounce with no dampening. At Kr = 0.0, the ball would stop at the wall.

            // Make sure the puck velocity and wall normal are facing each other
            float impact = XMVectorGetX ( XMVector3Dot ( wall-&gt;VectorNormal(), puck-&gt;VectorVelocity()) );
            if (impact &lt; 0.0f)
            {
                wallCollision = true;

                //// bounce the vector off the plane
                XMVECTOR VectorNormal = XMVector3Dot(wall-&gt;VectorNormal(), puck-&gt;VectorVelocity())*wall-&gt;VectorNormal();
                XMVECTOR VectorTangent = puck-&gt;VectorVelocity() - VectorNormal;

                puck-&gt;Velocity(VectorTangent - (XMVectorScale(VectorNormal, Kr)));
                puck-&gt;Position(contactPuckPosition);

                int segment = (int)(puck-&gt;Position().z / GameConstants::WallSegmentDepth);
                segment = max(min(segment, GameConstants::NumWallSegments-1), 0);

                auto tiles = m_wallTiles[segment];
                WallTile^ tile = tiles[i];
                if(tile-&gt;GetPowerup() == Powerup::Split)
                    SplitPucks();

                break;
            }
        }
    }

    return wallCollision;
}
</pre></p><h2>Drawing Maelstrom</h2><p>To draw the game, we wanted to use some advanced techniques. We decided to go with a light pre-pass deferred rendering pipeline with normal mapping. That’s a lot of jargon but it isn’t all that complicated once you know what the jargon means, so let’s break it down.</p><p>When you draw something in 3D, there are three things that come together to determine the final color of each pixel on the screen: meshes, materials, and lights. A mesh is a collection of triangles that make up a game object (such as a wall tile in Maelstrom). On its own, a mesh is just a bunch of dots and lines. A material makes a mesh look like something. It could be as simple as a solid color but usually it’s a texture and sometimes it’s more (the wall tiles in Maelstrom use both a texture and a normal map to define their material properties). Lastly, lights transform materials by determining how bright they should appear and what sort of tint, if any, they should have. Without lights you would either have complete darkness or you would have flat lighting (where everything has a uniform brightness and adding a tint color would uniformly tint everything on the screen).</p><h2>Forward Rendering vs. Deferred Rendering vs. Light Pre-Pass Rendering</h2><p>The simplest approach to drawing 3D graphics is something called forward rendering. With forward rendering, drawing consists of rendering the mesh and calculating its material and all the lights that affect the material all at the same time. The more lights you add, the more complicated your shaders become since you have to determine whether each light affects the material and if so how much. (Ok, so there’s also multi-pass forward rendering, but that has its own problems – more passes mean longer render times and thus a lower frame rate – and we wanted to keep the descriptions simple).</p><p>In the last 5 years, many games started using a technique called deferred rendering. In classic deferred rendering, there are two rendering passes. The first pass renders the positions, normals, and material values of all the meshes in the scene to something called a G-Buffer (two or more render targets); nothing is actually drawn to the screen in this first pass. The second pass uses the data from the G-Buffer (which tells us everything we need to know about the geometry that appears at each screen pixel) and combines it with the lights to create the final image that you see. By doing this, we decouple geometry and lighting. This makes it possible to add more lights to the scene with a much smaller performance impact than in forward rendering since we don’t need to create a really complex pixel shader to handle all the lights (single-pass forward rendering) or draw the geometry over and over again for each light (multi-pass forward rendering).</p><p>There are drawbacks to classic deferred rendering though. Even a minimal G-Buffer takes up quite a bit of memory and the more different types of materials you want to support, the larger the G-Buffer will need to be. Wolfgang Engel, an XNA/DirectX MVP, came up with a variation on deferred rendering which he called <a href="http://diaryofagraphicsprogrammer.blogspot.com/2008/03/light-pre-pass-renderer.html">Light Pre-Pass Rendering</a>. This is a three pass technique. We once again use a G-Buffer, but in this case it is smaller than the classic deferred rendering G-Buffer and can even be squeezed down to a single render target which makes it viable for graphics hardware which does not support drawing to multiple render targets at the same time.</p><p>The G-Buffer is created in the first pass by rendering all the scene geometry. It only needs to store normals and the geometry’s world position. We stored the world position of the geometry at that screen position in one render target and its normal at that screen position in second render target for simplicity.</p><p>The next pass draws the lights to a light accumulation buffer. The buffer starts out entirely dark and each light that is rendered adds brightness (and tint, if any) to the light buffer. These lighting calculations take into account the normal and world position of the geometry that is at each screen position, drawing the values from the G-Buffer, such that each light only affects the pixels it is supposed to have an impact on. In Maelstrom we ended up only using point lights (spheres of light that fade out as you get further from the light’s position), but you can use any kind of light you can imagine (spot lights and directional lights are the two other common light types). Adding more lights has a very low impact on rendering time and this kind of lighting tends to be much easier for the designer to work with since there’s no need for him or her to understand HLSL or even any complicated C&#43;&#43; in order to add, remove, reposition, or otherwise change any lights.</p><p>The final pass draws the geometry a second time. This time, though, all the lighting calculations are done so all we do here is just render the meshes with their appropriate materials, adjust the color values and intensities from the material based on the light buffer value, and we’re done. Each rendering style (forward, deferred, and light pre-pass) has its own benefits and drawbacks, but in this case light pre-pass was a good solution and choosing it let us show how a state-of-the-art graphics technique works.</p><h2>Normal Mapping</h2><p>We also incorporated normal mapping. Normal mapping makes us of a special texture (a normal map) in addition to the regular texture that a material has. Normals are values used in lighting calculations to determine how much a particular light should affect a particular pixel. If you wanted to draw a brick wall, you would typically create two triangles that lined up to form a rectangle and you would apply a texture of a brick wall to them as their material. The end result of that doesn’t look very convincing though since unlike a real brick wall there are no grooves in the mortared area between each brick since our brick and mortar is just a flat texture applied to flat triangles. We could fix this by changing from two triangles to a fully modeled mesh with actual grooves, but that would add thousands of extra vertices which would lower the frame rate.</p><p>So instead we use a normal map, which fakes it. One of the reasons that the two triangles &#43; a brick wall texture approach doesn’t look right is because the lighting doesn’t behave correctly when compared to a real brick wall (or to a fully modeled mesh of a real brick wall). The normals point straight out perpendicular from the face of the rectangle whereas if we had the fully modeled mesh with actual grooves, the surface normals would only point straight out on the bricks themselves and they would curve along the mortared areas such that the lighting calculations would end up giving us the right levels of light and dark depending on the location and direction of the light. That’s where a normal map comes in. The normal map (which you can generate using a plugin for Adobe Photoshop or GIMP or by modeling a real brick wall in 3DSMax, Maya, or Blender which you then “bake” a normal map from) allows us to get the same lighting effect as we would with a fully modeled mesh while still keeping the simple two triangle &#43; a brick wall texture approach that gives us really good performance for our game. There are limits to the effectiveness of normal mapping (you can’t use it to fake anything too deep and it doesn’t hold up as well if the camera can get really close to the object) but in Maelstrom it allowed us to keep the walls as simple triangles (like the two triangles &#43; a brick wall texture example above) while making it seem like there were geometric grooves in the wall. Here’s a before and after screenshot using normal mapping:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/MaelstromNoBloomNoNormalMapping%5B9%5D.png"><img title="MaelstromNoBloomNoNormalMapping" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/MaelstromNoBloomNoNormalMapping_thumb%5B8%5D.png" alt="MaelstromNoBloomNoNormalMapping" width="640" height="360" border="0"></a></p><p>&nbsp;</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/MaelstromWithoutBloom%5B2%5D.png"><img title="MaelstromWithoutBloom" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/MaelstromWithoutBloom_thumb.png" alt="MaelstromWithoutBloom" width="640" height="360" border="0"></a></p><h2>Post-Processing Effects</h2><p>We also used several post-processing effects. The first was the bloom effect. Bloom is an effect that analyzes a rendered image, identifies parts that are above a certain brightness threshold, and makes those areas brighter and adds a peripheral glow to them as well, giving it a look and feel that is similar to a neon sign or to the light cycles in the movie <em>Tron</em>. Here’s the same shot as above with the addition of bloom:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/MaelstromWithNormalMapping%5B27%5D.png"><img title="MaelstromWithNormalMapping" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/MaelstromWithNormalMapping_thumb%5B18%5D.png" alt="MaelstromWithNormalMapping" width="640" height="360" border="0"></a></p><p>We also made use of two different damage effects. Whenever the player took damage, we had a reddish tinge around the edge of the screen. This was simply a full screen overlay texture that is actually white but is tinted red by the shader. It is alpha-blended over the final rendered scene and fades out over the course of a couple of seconds. Rather than fading out linearly, we use a power curve which helps to sell the effect as being more complicated than it really is.</p><p>Lastly we added in some damage particles. The particles themselves were created using a geometry shader. The vertex shader took in a series of points in world space and passed these points along to the geometry shader. The geometry shader expanded these points into two triangles by generating the missing vertices and applying the world-view-projection transformation matrix to transform the positions from world coordinates to homogeneous coordinates so that they can then be rasterized correctly by D3D and the resulting pixels passed along to the pixel shader. Once again we used a simple texture with alpha blending to simulate much more complicated geometry than we were actually drawing. In this case we also made use of a texture atlas (an image made up of smaller images) which, in conjunction with the randomizer we used to generate the initial vertices for the particles, allowed us to have several different particle textures. Like with the power curve for the damage texture, the texture atlas allowed us to make the particles seem more complex than they really were. It also let us show off the use of a geometry shader, a feature that was added in DirectX 10 and requires DirectX 10 or higher hardware.</p><h3>Audio</h3><p>All audio was done using the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee415737%28v=vs.85%29.aspx">XAudio2 API</a>.&nbsp; Thankfully, we were able to get a huge head start by using some of the code from the sample project we started from.&nbsp; The audio engine sets up the very basics of XAudio2, and then wraps that with a simpler API for the rest of the application to call.</p><p>We don’t have many sound effects, so we on startup, we load all sounds effects and music cues into a <strong>std::map</strong>, keyed on a <strong>SoundCue</strong> enum.&nbsp; Sounds are loaded using the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms694197%28v=vs.85%29.aspx">Media Foundation</a> classes, and the resulting byte data of the sound (and some format information) are stored in our <strong>SoundEffect</strong> class.</p><p><pre class="brush: cpp">
void AudioEngine::Initialize()
{
    m_audio = ref new Audio();
    m_audio-&gt;CreateDeviceIndependentResources();

    m_mediaReader = ref new MediaReader();

    // Impacts
    m_soundMap[SoundCue::BallLaunch]    = LoadSound(&quot;Sounds\\Impacts\\BallLaunch.wav&quot;);
    m_soundMap[SoundCue::Buzz]          = LoadSound(&quot;Sounds\\Impacts\\Buzz.wav&quot;);
    m_soundMap[SoundCue::Impact1]       = LoadSound(&quot;Sounds\\Impacts\\Impact1.wav&quot;);
    m_soundMap[SoundCue::Impact2]       = LoadSound(&quot;Sounds\\Impacts\\Impact2.wav&quot;);

...

}

SoundEffect^ AudioEngine::LoadSound(String^ filename)
{
    Array&lt;byte&gt;^ soundData = m_mediaReader-&gt;LoadMedia(filename);
    auto soundEffect = ref new SoundEffect();
    soundEffect-&gt;Initialize(m_audio-&gt;SoundEffectEngine(), m_mediaReader-&gt;GetOutputWaveFormatEx(), soundData);
    return soundEffect;
}
</pre></p><p>When the game needs to play a sound, it simply calls the <strong>PlaySound</strong> method, passing in the cue to play, and the volume to play it at.&nbsp; <strong>PlaySound</strong> keys into the sound map, getting the associated <strong>SoundEffect</strong>, and plays it.</p><p><pre class="brush: cpp">
void AudioEngine::PlaySound(SoundCue cue, float volume, bool loop)
{
    m_soundMap[cue]-&gt;Play(volume, loop);
}
</pre></p><h3>MJPEG Cameras</h3><p>To achieve the effect of seeing the opponent in stereoscopic 3D, we strapped two <a href="http://www.axis.com/products/cam_m1014/">Axis M1014</a> network cameras side-by-side.&nbsp; Using Brian’s <a href="http://mjpeg.codeplex.com/">MJPEG Decoder</a> library, with a special port to Windows Runtime, individual JPEG frames were pulled off each camera, and then applied to a texture at the back of the arena.&nbsp; The image from the left camera is drawn when DirectX renders the player’s left eye, and the frame from the right camera is drawn when DirectX renders the right eye.&nbsp; This is a cheap and simple way to pull off live stereoscopic 3D.</p><p><pre class="brush: cpp">
void MjpegCamera::Update(GameEngine^ engine)
{
    if(m_decoderLeft != nullptr)
        UpdateTexture(m_decoderLeft-&gt;CurrentFrame, &amp;textureLeft);

    if(m_decoderRight != nullptr)
        UpdateTexture(m_decoderRight-&gt;CurrentFrame, &amp;textureRight);

    Face::Update(engine);
}

void MjpegCamera::Render(_In_ ID3D11DeviceContext *context, _In_ ID3D11Buffer *primitiveConstantBuffer, _In_ bool isFirstPass, int eye)
{
    if(eye == 1 &amp;&amp; textureRight != nullptr)
        m_material-&gt;SetTexture(textureRight.Get());
    else if(textureLeft != nullptr)
        m_material-&gt;SetTexture(textureLeft.Get());

    GameObject::Render(context, primitiveConstantBuffer, isFirstPass);
}
</pre></p><p>With the distance between the cameras being about the distance of human eyes (called the intra-axial distance), the effect works pretty well!</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0284%5B5%5D.jpg"><img title="IMG_0284" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0284_thumb%5B3%5D.jpg" alt="IMG_0284" width="640" height="480" border="0"></a></p><h3>Tablet/Controller</h3><p>The Tablet controller is the touch screen that lets the player control their 3D paddle in the Game Console app. For this part of the game system, there wasn't a reason to dive deep into DirectX and C&#43;&#43; since the controller is neither stereoscopic or visually intense, so we kept things simple with C#.</p><p>Since the controller would also serve as our attract screen in the podium to entice potential players, we wanted to have the wait screen do something eye-catching. However, if you are moving from C# in WPF to C# and XAML in WinRT and are used to taking advantage of some of the more common &quot;memory hoggish UX hacks&quot; from WPF, you'll quickly find them absent in WinRT! For example, we no longer have <strong>OpacityMask</strong>, non-rectangular clipping paths or the ability to render a <strong>UIElement</strong> to a Bitmap. Our bag of UX tricks may be in need of an overhaul. However, what we do get in C# / XAML for WinRT is Z rotation, which is something we've had in Silverlight but I personally have been begging for in WPF for a long time.</p><p>Therefore, the opening animation in the controller is a procedurally generated effect that rotates PNG &quot;blades&quot; in 3D space, creating a very compelling effect. Here is how it works. The <strong>Blade</strong> user control is a simple canvas that displays one of a few possible blade images. The <strong>Canvas</strong> has a <strong>RenderTransform</strong> to control the scale and rotation and a <strong>PlaneProjection</strong> which allows us to rotate the blade graphic in X, Y and Z space.</p><p><pre class="brush: xml">
&lt;Canvas&gt;
    &lt;Canvas.RenderTransform&gt;
        &lt;ScaleTransform x:Name=&quot;scale&quot; ScaleX=&quot;1.0&quot; ScaleY=&quot;1.0&quot; CenterX=&quot;0&quot; CenterY=&quot;0&quot;/&gt;
    &lt;/Canvas.RenderTransform&gt;
    &lt;Canvas.Projection&gt;
        &lt;PlaneProjection x:Name=&quot;projection&quot; CenterOfRotationX=&quot;0&quot; CenterOfRotationY=&quot;0&quot; CenterOfRotationZ=&quot;0&quot; RotationX=&quot;00&quot; RotationY=&quot;0&quot; RotationZ=&quot;0&quot;/&gt;
    &lt;/Canvas.Projection&gt;
    &lt;Image x:Name=&quot;img0&quot; Width=&quot;300&quot; Height=&quot;100&quot; Canvas.Left=&quot;-4&quot; Canvas.Top=&quot;-12&quot; Source=&quot;Images/s0.png&quot;/&gt;
&lt;/Canvas&gt;
</pre></p><p>Each Blade is added dynamically to the Controller when the Tablet application first loads, stored in a <strong>List</strong> to have it's <strong>Update</strong>() method called during the <strong>CompositionTarget</strong>.<strong>Rendering</strong>() loop.</p><p><pre class="brush: csharp">
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    canvas_blades.Children.Clear();
    _blades.Clear();
    
    for (int i = 0; i &lt; NumBlades; i&#43;&#43;)
    {
        Blade b = new Blade { X = 950.0, Y = 530.0 };
        int id = _rand.Next(0, 5);
        b.SetBlade(id);
        b.Speed = .1 &#43; id * .1;
        SeedBlade(b);
        _blades.Add(b);
        canvas_blades.Children.Add(b);
    }
}

void CompositionTarget_Rendering(object sender, object e)
{
    if(_inGame)
    {
        paddle.Update();
    }
    else if(_isClosing)
    {
        foreach (Blade b in _blades)
            b.UpdateExit();
    }
    else
    {
        foreach (Blade b in _blades)
            b.Update();
    }
}
</pre></p><p>Since each Blade has been assigned an individual speed and angle of rotation along all three axis, they have a very straightforward <strong>Update</strong> function. The reason we keep the rotation values between -180 and 180 during the spinning loop is to make it easier to spin them out zero when we need them to eventually leave the screen.</p><p><pre class="brush: csharp">
public void Update()
{
   _rotX &#43;= Speed;
   _rotZ &#43;= Speed;
   _rotY &#43;= Speed;

   if (_rotX &gt; 180) _rotX -= 360.0;
   if (_rotX &lt; -180) _rotX &#43;= 360.0;
   if (_rotY &gt; 180) _rotY -= 360.0;
   if (_rotY &lt; -180) _rotY &#43;= 360.0;
   if (_rotZ &gt; 180) _rotZ -= 360.0;
   if (_rotZ &lt; -180) _rotZ &#43;= 360.0;

   projection.RotationX = _rotX;
   projection.RotationY = _rotY;
   projection.RotationZ = _rotZ;
}

public void UpdateExit()
{
   _rotX *= .98;
   _rotZ *= .98;
   _rotY &#43;= (90.0 - _rotY) * .1;

   projection.RotationX = _rotX;
   projection.RotationY = _rotY;
   projection.RotationZ = _rotZ;
}
</pre></p><h3>&nbsp;</h3><h3>Network</h3><p>To continue the experiment of blending C# and C&#43;&#43; code, the network communication layer was written in C# as a Windows Runtime component.&nbsp; Two classes are key to the system: <strong>SocketClient</strong> and <strong>SocketListener</strong>.&nbsp; Player one’s game console starts a <strong>SocketListener</strong> to listen for incoming connections from each game controller, as well as player two’s game console.&nbsp; Each of those use a <strong>SocketClient</strong> object to make the connection.</p><p>In either case, once the connection is made, the client and the listener sit and wait for data to be transmitted.&nbsp; Data must be sent as an object which implements our <strong>IGamePacket</strong> interface.&nbsp; This contains two important methods: <strong>FromDataReaderAsync</strong> and <strong>WritePacket</strong>.&nbsp; These methods serialize and deserialze the byte data to/from an <strong>IGameState</strong> packet of whatever type is specified in the <strong>PacketType</strong> property.</p><p><pre class="brush: cpp">
namespace Coding4Fun.Maelstrom.Communication
{
    public enum PacketType
    {
        UserInputPacket = 0,
        GameStatePacket
    }
    
    public interface IGamePacket
    {
        PacketType Type { get; }
        
        IAsyncAction FromDataReaderAsync(DataReader reader);
        void WritePacket(DataWriter writer);
    }
}
</pre></p><p>The controllers write <strong>UserInputPacket</strong>s to the game console, consisting of X,Y positions of the paddle, as well as whether the player has tapped the screen to begin.</p><p><pre class="brush: csharp">
public sealed class UserInputPacket : IGamePacket
{
    public PacketType Type { get { return PacketType.UserInputPacket; } }
    
    public UserInputCommand Command { get; set; }
    public Point3 Position { get; set; }
}
</pre></p><p>Player one’s game console writes a <strong>GameStatePacket</strong> to player' two’s game console, which consists of the positions of each paddle, each ball, the score, and which tiles are lit for the ball splitter power up.&nbsp; Player two’s <strong>Update</strong> and <strong>Render</strong> methods use this data to draw the screen appropriately.</p><h3>Hardware</h3><p>The hardware layer of this project is responsible for two big parts.&nbsp; One is a rumble effect that fires every time the player is hit, and the other is a lighting effect that changes depending on the game state.</p><p>As all good programmers do, we reused code from another project.&nbsp; We leveraged the proven web server from <a href="http://channel9.msdn.com/coding4fun/articles/Project-Detroit-An-Overview">Project Detroit</a> for our Netduino, but with a few changes.&nbsp; Here, we had static class “modules” which knew how to talk to the physical hardware, and “controllers” which handled items like a player scoring, game state animations, and taking damage.&nbsp; Because the modules are static classes, we can have them referenced in multiple classes without issue.</p><h2>NETMF Web Server</h2><p>When a request comes in, we perform the requested operation, and then return a new line character to verify we got the request. If you don’t return any data, some clients will actually fire a second request which then can cause some odd behaviors.&nbsp; The flow is as follows:</p><ol><li>Parse the URL </li><li>Get the target controller </li><li>Execute the appropriate action </li></ol><p><pre class="brush: csharp">
private static void WebServerRequestReceived(Request request)
{
    var start = DateTime.Now;
    Logger.WriteLine(&quot;Start: &quot; &#43; request.Url &#43; &quot; at &quot; &#43; DateTime.Now);
    
    try
    {
        var data = UrlHelper.ParseUrl(request.Url);
        
        var targetController = GetController(data);
        
        if (targetController != null)
        {
            targetController.ExecuteAction(data);
        }
    }
    catch (Exception ex0)
    {
        Logger.WriteLine(ex0.ToString());
    }
    
    request.SendResponse(NewLine);
    
    Logger.WriteLine(&quot;End: &quot; &#43; request.Url &#43; &quot; at &quot; &#43; DateTime.Now &#43; &quot; took: &quot; &#43; (DateTime.Now - start).Milliseconds);
}

public static IController GetController(UrlData data)
{
    if (data.IsDamage)
        return Damage;
    
    if (data.IsScore)
        return Score;
    
    if (data.IsGameState)
        return GameState;
    
    // can assume invalid
    return null;
}
</pre></p><h2>Making It Shake</h2><p>We used a Sparkfun MP3 trigger board, a subwoofer amplifier, and bass rumble plates to create this effect.&nbsp; The MP3 board requires power, and two jumpers to cause the MP3 to play.&nbsp; It has an audio jack that then gets plugged into the amplifier which powers the rumble plates.</p><p>From here, we just needed to wire a ground to the MP3 player’s ground pin, and the target pin on the MP3 player to a digital IO pin on the Netduino.&nbsp; In the code, we declare it as an <strong>OutputPort</strong> and give it an initial state of true.&nbsp; When we get a request, we toggle the pin on a separate thread.</p><p><pre class="brush: csharp">
private static readonly OutputPort StopMusic = new OutputPort(Pins.GPIO_PIN_D0, true);
private static readonly OutputPort Track1 = new OutputPort(Pins.GPIO_PIN_D1, true);
// .. more pins

public static void PlayTrack(int track)
{
    switch (track)
    {
        case 1:
            TogglePin(Track1);
            break;
            // ... more cases
        default:
            // stop all, invalid choice
            TogglePin(StopMusic);
            break;
    }
}

public static void Stop()
{
    TogglePin(StopMusic);
}

private static void TogglePin(OutputPort port)
{
    var t = new Thread(() =&gt;
    {
            port.Write(false);
            Thread.Sleep(50);
            port.Write(true);
    });
    
    t.Start();
}
</pre></p><h2>Lighting Up the Room</h2><p>For lighting, we used some <a href="http://www.usledsupply.com/shop/12v-rgb-flex-strip.html">RGB Lighting strips</a>.&nbsp; The strips can change a single color and use a PWM signal to do this.&nbsp; This is different than the lighting we used in Project Detroit which allowed us to individually control each LED and used SPI to communicate.&nbsp; We purchased an RGB amplifier to allow a PWM signal to power a 12 volt strip.&nbsp; We purchased ours from US LED Supply and the exact product was <a href="http://www.usledsupply.com/shop/rgb-mini-amplifier-ttl.html">RGB Amplifier 4A/Ch for interfacing with a Micro-Controller (PWM/TTL Input)</a>.</p><p>We alter the Duty Cycle to shift the brightness of the LEDs and do this on a separate thread.&nbsp; Below is a stripped down version of the lighting hardware class.</p><p><pre class="brush: csharp">
public static class RgbStripLighting
{
    private static readonly PWM RedPwm = new PWM(Pins.GPIO_PIN_D5);
    private static readonly PWM GreenPwm = new PWM(Pins.GPIO_PIN_D6);
    private static readonly PWM BluePwm = new PWM(Pins.GPIO_PIN_D9);
    
    private const int ThreadSleep = 50;
    private const int MaxValue = 100;
    
    const int PulsePurpleIncrement = 2;
    const int PulsePurpleThreadSleep = 100;
    
    private static Thread _animationThread;
    private static bool _killThread;
    
    #region game state animations
    public static void PlayGameIdle()
    {
        AbortAnimationThread();
        
        _animationThread = new Thread(PulsePurple);
        _animationThread.Start();
    }
    #endregion
        
            
    private static void PulsePurple()
    {
        while (!_killThread)
        {
            for (var i = 0; i &lt;= 50; i &#43;= PulsePurpleIncrement)
            {
                SetPwmRgb(i, 0, i);
            }
            
            for (var i = 50; i &gt;= 0; i -= PulsePurpleIncrement)
            {
                SetPwmRgb(i, 0, i);
            }
            
            Thread.Sleep(PulsePurpleThreadSleep);
        }
    }
    
    private static void AbortAnimationThread()
    {
        _killThread = true;
        
        try
        {
            if(_animationThread != null)
                    _animationThread.Abort();
        }
        catch (Exception ex0)
        {
            Debug.Print(ex0.ToString());
            Debug.Print(&quot;Thread still alive: &quot;);
            Debug.Print(&quot;Killed Thread&quot;);
        }
        
        _killThread = false;
    }
    
    private static void SetPwmRgb(int red, int green, int blue)
    {
        // typically, 0 == off and 100 is on
        // things flipped however for the lighting so building this in.
        
        red = MaxValue - red;
        green = MaxValue - green;
        blue = MaxValue - blue;
        
        red = CheckBound(red, MaxValue);
        green = CheckBound(green, MaxValue);
        blue = CheckBound(blue, MaxValue);
        
        RedPwm.SetDutyCycle((uint) red);
        GreenPwm.SetDutyCycle((uint) green);
        BluePwm.SetDutyCycle((uint) blue);
        
        Thread.Sleep(ThreadSleep);
    }
    
    public static int CheckBound(int value, int max)
    {
        return CheckBound(value, 0, max);
    }
    
    public static int CheckBound(int value, int min, int max)
    {
        if (value &lt;= min)
            value = min;
        else if (value &gt;= max)
            value = max;
        
        return value;
    }
}
</pre></p><h3>Conclusion</h3><p>We built this experience over the course of around 4 to 5 weeks.&nbsp; It was our first DirectX application in a very long time, and our first C&#43;&#43; application in a very long time.&nbsp; However, we were able to pick up the new platform and language changes fairly easily and create a simple, yet fun game in that time period.</p><h3>Attributions</h3><ul><ul><li>Music track - <a href="http://soundcloud.com/neosvsatm/bullet">&quot;FatLoad- The Bullet(no master)&quot; by FreaK NeoS</a> </li><li>Sound effects &#43; music edition - <a href="http://davidwallimann.com/">David Wallimann</a> </li><li>DirectX shaders - <a href="http://geekswithblogs.net/mikebmcl/Default.aspx">Michael McLaughlin</a> </li></ul></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:12ea0afdf04c46d0980ca101018434ed">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Maelstrom-An-Overview</comments>
      <itunes:summary>For //build/ 2012, we wanted to showcase what Windows 8 can offer developers.&amp;nbsp; There are a lot of projects showing off great things like contracts and Live Tiles, but we wanted to show off some of the lesser known features.&amp;nbsp; This project focuses on one of those: stereoscopic 3D with DirectX 11.1. Prior to DirectX 11.1, stereoscopic 3D required specific hardware and a custom API written for that hardware.&amp;nbsp; With DX11.1, stereoscopic 3D has been &amp;quot;democratized.&amp;quot;&amp;nbsp; Any GPU that supports DirectX 11.1 can be connected to any device which supports stereoscopic 3D, be it a projector, an LCD TV, or anything else.&amp;nbsp; Plug it in and DirectX does the rest. From the software side of things, any DX11.1 application can determine if the connected display supports stereoscopic 3D, and choose to render itself separately for the player&#39;s left and right eye. To showcase this feature, we decided to build a very simple game that would give the illusion of depth, but be easy to explain and play.&amp;nbsp; What&#39;s easier than Pong?&amp;nbsp; So, we built the world&#39;s most over-engineered game of 3D Pong named Maelstrom.  SoftwareEach player setup consists of two applications: the DirectX 11.1 game written in C&amp;#43;&amp;#43;, and the touch-screen controller written in C#/XAML.&amp;nbsp; Both are Windows Store applications.&amp;nbsp; Since this is a two player game, there are two instances of each application running, one per player.&amp;nbsp; All for applications are networked together using StreamSockets from the Windows Runtime.&amp;nbsp; The two controllers and player two&#39;s DirectX game connect to player one&#39;s DirectX game, which acts as the &amp;quot;master&amp;quot;.&amp;nbsp; Controller input is sent here, and, once the ball and paddle positions are calculated, the data is drawn for player one and sent to player two which draws the world from the other player&#39;s perspective.  Direct3D ApplicationGetting Started with stereoscopic DirectX11, C&amp;#43;&amp;#43;, and XAMLIf you have never worked with Direct</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Maelstrom-An-Overview</link>
      <pubDate>Tue, 20 Nov 2012 21:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Maelstrom-An-Overview</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/af11e27a-5854-40e9-b005-01f97846f491.png" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/c7f299fc-4bbf-45ee-84b3-d2460d947ceb.png" height="124" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/8ced263b-4c1a-469a-a02b-471d27bb6705.png" height="288" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Michael B. McLaughlin, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Michael B. McLaughlin, Rick Barraza</itunes:author>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Maelstrom-An-Overview/RSS</wfw:commentRss>
      <category>3D</category>
      <category>C++</category>
      <category>Coding4Fun</category>
      <category>Direct 3D</category>
      <category>DirectX 11</category>
      <category>NETMF</category>
      <category>Windows 8</category>
    </item>
  <item>
      <title>Maelstrom Video</title>
      <description><![CDATA[<p>Video footage for Maelstrom, our game shown off at //build/ 2012!&nbsp; Article &#43; source code coming soon...stay tuned!</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ff7a18156a4741a582e5a1040001ad03">]]></description>
      <comments>http://channel9.msdn.com/Blogs/BrianPeek/Maelstrom</comments>
      <itunes:summary>Video footage for Maelstrom, our game shown off at //build/ 2012!&amp;nbsp; Article &amp;#43; source code coming soon...stay tuned! </itunes:summary>
      <itunes:duration>11</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/BrianPeek/Maelstrom</link>
      <pubDate>Fri, 09 Nov 2012 19:18:17 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/BrianPeek/Maelstrom</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.mp3" expression="full" duration="11" fileSize="189720" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.mp4" expression="full" duration="11" fileSize="1128523" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.webm" expression="full" duration="11" fileSize="446293" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.wma" expression="full" duration="11" fileSize="110171" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.wmv" expression="full" duration="11" fileSize="1726559" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom_high.mp4" expression="full" duration="11" fileSize="2480804" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom_mid.mp4" expression="full" duration="11" fileSize="1735565" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom_Source.wmv" expression="full" duration="11" fileSize="13570225" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.ism/manifest" expression="full" duration="11" fileSize="8382" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/23e7/8a61c15c-5f47-4155-9982-038a179e23e7/Maelstrom.wmv" length="1726559" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek</dc:creator>
      <itunes:author>Brian Peek</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/BrianPeek/Maelstrom/RSS</wfw:commentRss>
      <category>C#</category>
      <category>C++</category>
      <category>Coding4Fun</category>
      <category>DirectX 11</category>
      <category>XAML</category>
    </item>
  <item>
      <title>Boxing Bots: An Overview</title>
      <description><![CDATA[<h2>Introduction</h2><p>In early January, we were tasked with creating a unique, interactive experience for the <a href="http://sxsw.com/interactive">SXSW Interactive</a> launch party with <a href="http://www.frogdesign.com/">Frog Design</a>. We bounced around many ideas, and finally settled on a project that Rick suggested during our first meeting: boxing robots controlled via Kinect.</p><p>The theme of the opening party was Retro Gaming, so we figured creating a life size version of a classic tabletop boxing game mashed up with a &quot;Real Steel&quot;-inspired Kinect experience would be a perfect fit. Most importantly, since this was going to be the first big project of the new Coding4Fun team, we wanted to push ourselves to create an experience that needed each of us to bring our unique blend of hardware, software, and interaction magic to the table under an aggressively tight deadline.</p><h2>Hardware</h2><p>The BoxingBots had to be fit a few requirements:</p><ol><li>They had to be fun </li><li>They had to survive for 4 hours, the length of the SXSW opening party </li><li>Each robot had to punch for 90 seconds at a time, the length of a round </li><li>They had to be life-size </li><li>They had to be Kinect-drivable </li><li>They had to be built, shipped, and reassembled for SXSW </li></ol><p>Creating a robot that could be beaten up for 4 hours and still work proved to be an interesting problem. After doing some research on different configurations and styles, it was decided we should leverage a prior project to get a jump start to meet the deadline. We repurposed sections of our Kinect drivable lounge chair, <a href="http://channel9.msdn.com/coding4fun/articles/Jellybean-the-Kinect-Drivable-Lounge-Chair">Jellybean</a>! This was an advantage because it contained many known items, such as the motors, motor controllers, and chassis material.&nbsp; Additionally, it was strong and fast, it was modular, and the code to drive it was already written.</p><p>Jellybean would only get us part of the way there, however.&nbsp; We also had to do some retrofitting to get it to work for our new project. The footprint of the base needed to shrink from 32x50 inches to 32x35 inches, while still allowing space to contain all of the original batteries, wheels, motors, motor controllers, switches, voltage adapters. We also had to change how the motors were mounted with this new layout, as well as provide for a way to easily &quot;hot swap&quot; the batteries out during the event. Finally, we had to mount an upper body section that looked somewhat human, complete with a head and punching arms.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0087%5B4%5D.jpg"><img title="IMG_0087" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0087_thumb%5B1%5D.jpg" alt="IMG_0087" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0089%5B9%5D.jpg"><img title="IMG_0089" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0089_thumb%5B4%5D.jpg" alt="IMG_0089" width="240" height="180" border="0"></a><br><strong>Experimenting with possible layouts</strong></p><p>The upper body had its own challenges, as it had to support a ton of equipment, including:</p><ul><li>Punching arms </li><li>Popping head </li><li>Pneumatic valves </li><li>Air manifold </li><li>Air Tank(s) </li><li>Laptop </li><li>Phidget interface board </li><li>Phidget relay boards </li><li>Phidget LED board </li><li>Xbox wireless controller PC transmitter / receiver </li><li>Chest plate </li><li>LEDs </li><li>Sensors to detect a punch </li></ul><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0113%5B5%5D.jpg"><img title="IMG_0113" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0113_thumb%5B2%5D.jpg" alt="IMG_0113" width="500" height="667" border="0"></a><br><strong>Brian and Rick put together one of the upper frames</strong></p><h3>Punching and Air Tanks</h3><p>We had to solve the problem of getting each robot to punch hard enough to register a hit on the opponent bot while not breaking the opponent bot (or itself). Bots also had to withstand a bit of side load in case the arms got tangled or took a side blow. Pneumatic actuators provided us with a lot of flexibility over hydraulics or an electrical solution since they are fast, come in tons of variations, won't break when met with resistance, and can fine tuned with a few onsite adjustments.</p><p>To provide power to the actuators, the robots had two 2.5 gallon tanks pressurized to 150psi, with the actuators punching at ~70psi.&nbsp; We could punch for about five 90-second rounds before needing to re-pressurize the tanks.&nbsp; Pressurizing the onboard tanks was taken care of by a pair of off-the-shelf DeWalt air compressors.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0134%5B4%5D.jpg"><img title="IMG_0134" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0134_thumb%5B1%5D.jpg" alt="IMG_0134" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0184%5B4%5D.jpg"><img title="IMG_0184" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0184_thumb%5B1%5D.jpg" alt="IMG_0184" width="240" height="180" border="0"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0279%5B4%5D.jpg"><img title="IMG_0279" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0279_thumb%5B1%5D.jpg" alt="IMG_0279" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0172%5B4%5D.jpg"><img title="IMG_0172" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0172_thumb%5B1%5D.jpg" alt="IMG_0172" width="240" height="180" border="0"></a></p><h3>The Head</h3><p>It wouldn’t be a polished game if the head didn’t pop up on the losing bot, so we added another pneumatic actuator to raise and lower the head, and some extra red and blue LEDs. This pneumatic is housed in the chest of the robot and is triggered only when the game has ended.</p><p>To create the head, we first prototyped a concept with cardboard and duct tape. A rotated welding mask just happened to provide the shape we were going for on the crown, and we crafted each custom jaw with a laser cutter.&nbsp; We considered using a mold and vacuum forming to create something a bit more custom, but had to scrap the idea due to time constraints.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0169%5B4%5D.jpg"><img title="IMG_0169" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0169_thumb%5B1%5D.jpg" alt="IMG_0169" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0201%5B4%5D.jpg"><img title="IMG_0201" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0201_thumb%5B1%5D.jpg" alt="IMG_0201" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0268%5B4%5D.jpg"><img title="IMG_0268" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0268_thumb%5B1%5D.jpg" alt="IMG_0268" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0291%5B4%5D.jpg"><img title="IMG_0291" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0291_thumb%5B1%5D.jpg" alt="IMG_0291" width="240" height="180" border="0"></a></p><h3>Sensors</h3><p>Our initial implementation for detecting punches failed due to far too many false positives. We thought using IR distance sensors would be a good solution since we could detect a “close” punch and tell the other robot to retract the arm before real contact. The test looked promising, but in practice, when the opposite sensors were close, we saw a lot of noise in the data. The backup and currently implemented solution was to install simple push switches in the chest and detect when those are clicked by the chest plate pressing against them.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0200%5B4%5D.jpg"><img title="IMG_0200" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0200_thumb%5B1%5D.jpg" alt="IMG_0200" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0205%5B4%5D.jpg"><img title="IMG_0205" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0205_thumb%5B1%5D.jpg" alt="IMG_0205" width="240" height="180" border="0"></a></p><h3>Power</h3><p>Different items required different voltages. The motors and pneumatic valves required 24V, the LEDs required 12V and the USB hub required 5V. We used Castle Pro BEC converters to step down the voltages. These devices are typically used in RC airplanes and helicopters.</p><h3>Shipping</h3><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0278%5B4%5D.jpg"><img title="IMG_0278" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0278_thumb%5B1%5D.jpg" alt="IMG_0278" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0280%5B4%5D.jpg"><img title="IMG_0280" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0280_thumb%5B1%5D.jpg" alt="IMG_0280" width="240" height="180" border="0"></a></p><p>So how does someone ship two 700lb robots from Seattle to Austin? We did it in 8 crates. <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' />. The key thing to note is that the tops and bottoms of each robot were separated. Any wire that connected the two parts had to be able to be disconnected in some form. This affected the serial cords and the power cords (5V, 12V, 24V).</p><h2>Software</h2><p>The software and architecture went through a variety of iterations during development. The final architecture used 3 laptops, 2 desktops, an access point, and a router. It's important to note that the laptops of Robot 1 and Robot 2 are physically mounted on the backs of each Robot body, communicating through WiFi to the Admin console. The entire setup looks like the following diagram:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/network%5B4%5D.png"><img title="network" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/network_thumb%5B2%5D.png" alt="network" width="387" height="426" border="0"></a></p><h3><strong>Admin Console</strong></h3><p>The heart of the infrastructure is the Admin Console. Originally, this was also intended to be a scoreboard to show audience members the current stats of the match, but as we got further into the project, we realized this wouldn't be necessary. The robots are where the action is, and people's eyes focus there. Additionally, the robots themselves display their current health status via LEDs, so duplicating this information isn't useful. However, the admin side of this app remains.</p><h3><strong>Sockets</strong></h3><p>The admin console is the master controller for the game state and utilizes socket communication between it, the robots, and the user consoles. A generic socket handler was written to span each computer in the setup. The <strong>SocketListener</strong> object allows for incoming connections to be received, while the <strong>SocketClient</strong> allows clients to connect to those <strong>SocketListeners</strong>. These are generic objects, which must specify objects of type <strong>GamePacket</strong> to send and receive:</p><p><pre class="brush: csharp">
public class SocketListener&lt;TSend, TReceive&gt; where TSend : GamePacket                                                
                                             where TReceive : GamePacket, new()
</pre></p><p><br>&nbsp;</p><p><strong>GamePacket</strong> is a base class from which specific packets inherit:</p><p><pre class="brush: csharp">
public abstract class GamePacket
{
    public byte[] ToByteArray() 
    {   
        MemoryStream ms = new MemoryStream();           
        BinaryWriter bw = new BinaryWriter(ms);
                
        try
        {           
            WritePacket(bw);
        }
        catch(IOException ex)
        {
            Debug.WriteLine(&quot;Error writing packet: &quot; &#43; ex);
        }
        
        return ms.ToArray();
    }
        
    public void FromBinaryReader(BinaryReader br)
    {        
        try
        {    
            ReadPacket(br);       
        }
        catch(IOException ex)       
        {
            Debug.WriteLine(&quot;Error reading packet: &quot; &#43; ex);
        }
    }
    
    public abstract void WritePacket(BinaryWriter bw);
    public abstract void ReadPacket(BinaryReader br);
}
</pre></p><p>For example, in communication between the robots and the admin console, <strong>GameStatePacket</strong> and <strong>MovementDescriptorPacket</strong> are sent and received. Each <strong>GamePacket</strong> must implement its own <strong>ReadPacket</strong> and <strong>WritePacket</strong> methods to serialize itself for sending across the socket.</p><p>Packets are sent between machines every &quot;frame&quot;. We need the absolute latest game state, robot movement, etc. at all times to ensure the game is functional and responsive.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B20%5D-2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B12%5D-3.png" alt="image" width="640" height="278" border="0"></a></p><p>As is quite obvious, absolutely no effort was put into making the console &quot;pretty&quot;. This is never seen by the end users and just needs to be functional. Once the robot software and the user consoles are started, the admin console initiates connections to each of those four machines. Each machine runs the <strong>SocketListener</strong> side of the socket code, while the Admin console creates four <strong>SocketClient</strong> objects to connect to each those. Once connected, the admin has control of the game and can start, stop, pause, and reset a match by sending the appropriate packets to everyone that is connected.</p><h3><strong>Robot</strong></h3><p>The robot UI is also never intended to be seen by an end user, and therefore contains only diagnostic information.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B19%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B11%5D-1.png" alt="image" width="640" height="361" border="0"></a></p><p>Each robot has a wireless Xbox 360 controller connected to it so it can be manually controlled. The UI above reflects the positions of the controller sticks and buttons. During a match, it's possible for a bot to get outside of our &quot;safe zone&quot;. One bot might be pushing the other, or the user may be moving the bot toward the edge of the ring. To counter this, the player's coach can either temporarily move the bot, turning off Kinect input, or force the game into &quot;referee mode&quot; which pauses the entire match and turns off Kinect control on both sides. In either case, the robots can be driven with the controllers and reset to safe positions. Once both coaches signal that the robots are reset, the admin can then resume the match.</p><h3>Controlling Hardware</h3><p>Phidget hardware controlled our LEDs, relays, and sensors. Getting data out of a Phidget along with actions, such as opening and closing a relay, is shockingly easy as they have pretty straightforward C# APIs and samples, which is why they typically are our go-to product for projects like this.</p><p>Below are some code snippets for the LEDs, relays, and sensor.</p><p><strong>LEDs – from LedController.cs</strong></p><p>This is the code that actually updates the health LEDs in the robot's chest. The LEDs were put on the board in a certain order to allow this style of iteration. We had a small issue of running out of one color of LEDs so we used some super bright ones and had to reduce the power levels to the non-super bright LEDs to prevent possible damage:</p><p><pre class="brush: csharp">
private void UpdateLedsNonSuperBright(int amount, int offset, int brightness)
{
    for (var i = offset; i &lt; amount &#43; offset; i&#43;&#43;)
    {
        _phidgetLed.leds[i] = brightness / 2;
    }
}

private void UpdateLedsSuperBright(int amount, int offset, int brightness)
{
    for (var i = offset; i &lt; amount &#43; offset; i&#43;&#43;)
    {
        _phidgetLed.leds[i] = brightness;
    }
}
</pre></p><p>&nbsp;</p><p><strong>Sensor data – from SensorController.cs</strong></p><p>This code snippet shows how we obtain the digital and analog inputs from the Phidget 8/8/8 interface board:</p><p><pre class="brush: csharp">
public SensorController(InterfaceKit phidgetInterfaceKit) : base(phidgetInterfaceKit)
{    
    PhidgetInterfaceKit.ratiometric = true;
}

public int PollAnalogInput(int index)
{
    return PhidgetInterfaceKit.sensors[index].Value;
}

public bool PollDigitalInput(int index)
{
    return PhidgetInterfaceKit.inputs[index];
}
</pre></p><p>&nbsp;</p><p><strong>Relays – from RelayController.cs</strong></p><p>Electrical relays fire our pneumatic valves. These control the head popping and the arms punching. For our application, we wanted the ability to reset the relay automatically. When the relay is opened, an event is triggered and we create an actively polled thread to validate whether we should close the relay. The reason why we actively poll is someone could be quickly toggling the relay. We wouldn't want to close it on accident. The polling and logic does result in a possible delay or early trigger for closing the relay, but for the BoxingBots the difference of 10ms for a relay closing is acceptable:</p><p><pre class="brush: csharp">
public void Open(int index, int autoCloseDelay)
{   
    UseRelay(index, true, autoCloseDelay);
}

public void Close(int index)
{
    UseRelay(index, false, 0);
}

private void UseRelay(int index, bool openRelay, int autoCloseDelay)
{
    AlterTimeDelay(index, autoCloseDelay);
    PhidgetInterfaceKit.outputs[index] = openRelay;
}

void _relayController_OutputChange(object sender, OutputChangeEventArgs e)
{
    // closed
    if (!e.Value)
        return;

    ThreadPool.QueueUserWorkItem(state =&gt;
    {                                          
        if (_timeDelays.ContainsKey(e.Index))
        {                                              
            while (_timeDelays[e.Index] &gt; 0)                       
            {
                Thread.Sleep(ThreadTick);           
                _timeDelays[e.Index] -= ThreadTick;
            }                                            
        }
                                            
        Close(e.Index);
                                        
    });
}

public int GetTimeDelay(int index)
{
    if (!_timeDelays.ContainsKey(index))
        return 0;
    return _timeDelays[index];
}

public void AlterTimeDelay(int index, int autoCloseDelay)
{
    _timeDelays[index] = autoCloseDelay;
}
</pre></p><p>&nbsp;</p><h3><strong>User Console</strong></h3><p>&nbsp;</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0297%5B5%5D.jpg"><img title="IMG_0297" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0297_thumb%5B2%5D.jpg" alt="IMG_0297" width="500" height="375" border="0"></a></p><p>Since the theme of the party was Retro Gaming, we wanted to go for an early 80's Sci-fi style interface, complete with starscape background and solar flares! We wanted to create actual interactive elements, though, to maintain the green phosphor look of early monochrome monitors. Unlike traditional video games, however, the screens are designed not as the primary focus of attention, but rather to help calibrate the player before the round and provide secondary display data during the match. The player should primarily stay focused on the boxer during the match, so the interface is designed to sit under the players view line and serve as more of a dashboard during each match.</p><p>However, during calibration before each round, it is important to have the player understand how their core body will be used to drive the Robot base during each round. To do this, we needed to track an average of the joints that make up each fighter's body core. We handled the process by creating a list of core joints and a variable that normalizes the metric distances returned from the Kinect sensor into a human-acceptable range of motion:</p><p><pre class="brush: csharp">
private static List&lt;JointType&gt; coreJoints = newList&lt;JointType&gt;( 
    newJointType[] {
        JointType.AnkleLeft,
        JointType.AnkleRight,
        JointType.ShoulderCenter,
        JointType.HipCenter
    });
private const double RangeNormalizer = .22;
private const double NoiseClip = .05;
</pre></p><p>And then during each skeleton calculation called by the game loop, we average the core positions to determine the averages of the players as they relate to their playable ring boundary:</p><p><pre class="brush: csharp">
public staticMovementDescriptorPacket AnalyzeSkeleton(Skeleton skeleton)
{           
    // ...

    CoreAverageDelta.X = 0.0;
    CoreAverageDelta.Z = 0.0;
    foreach (JointType jt in CoreJoints)
    {
        CoreAverageDelta.X &#43;= skeleton.Joints[jt].Position.X - RingCenter.X;
        CoreAverageDelta.Z &#43;= skeleton.Joints[jt].Position.Z - RingCenter.Z;
    }

    CoreAverageDelta.X /= CoreJoints.Count * RangeNormalizer;
    CoreAverageDelta.Z /= CoreJoints.Count * RangeNormalizer;

    // ...

    if (CoreAverageDelta.Z &gt; NoiseClip || CoreAverageDelta.Z &lt; -NoiseClip)
    {
        packet.Move = -CoreAverageDelta.Z;
    }

    if (CoreAverageDelta.X &gt; NoiseClip || CoreAverageDelta.X &lt; -NoiseClip)
    {
        packet.Strafe = CoreAverageDelta.X;
    }
}
</pre></p><p>In this way, we filter out insignificant data noise and allow the player's average core body to serve as a joystick for driving the robot around. Allowing them to lean at any angle, the move and strafe values are accordingly set to allow for a full 360 degrees of movement freedom, while at the same time not allowing any one joint to unevenly influence their direction of motion.</p><p>Another snippet of code that may be of interest is the WPF3D rendering we used to visualize the skeleton. Since the Kinect returns joint data based off of a center point, it is relatively easy to wire up a working 3D model in WPF3D off of the skeleton data, and we do this in the ringAvatar.xaml control.</p><p>In the XAML, we simply need a basic <strong>Viewport3D</strong> with camera, lights, and an empty <strong>ModelVisual3D</strong> container to hold or squares. The empty container looks like this:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p><p><pre class="brush: xml">
&lt;ModelVisual3D x:Name=&quot;viewportModelsContainer2&quot;&gt;                   
    &lt;ModelVisual3D.Transform&gt;
        &lt;Transform3DGroup&gt;           
            &lt;RotateTransform3D x:Name=&quot;bodyRotationCenter&quot; CenterX=&quot;0&quot; CenterY=&quot;0&quot; CenterZ=&quot;0&quot;&gt;      
                &lt;RotateTransform3D.Rotation&gt;             
                    &lt;AxisAngleRotation3D x:Name=&quot;myAngleRotation&quot; Axis=&quot;0,1,0&quot; Angle=&quot;-40&quot;/&gt;                 
                &lt;/RotateTransform3D.Rotation&gt;           
            &lt;/RotateTransform3D&gt; 
        &lt;/Transform3DGroup&gt; 
    &lt;/ModelVisual3D.Transform&gt;
&lt;/ModelVisual3D&gt;
</pre></p><p>In the code, we created a generic <strong>WPF3DModel</strong> that inherits from <strong>UIElement3D</strong> and is used to store the basic positioning properties of each square. In the constructor of the object, though, we can pass a reference key to a XAML file that defines the 3D mesh to use:</p><p><pre class="brush: csharp">
public WPF3DModel(string resourceKey)
{
    this.Visual3DModel = Application.Current.Resources[resourceKey] as Model3DGroup;
}
</pre></p><p>This is a handy trick when you need to do a fast WPF3D demo and require a certain level of flexibility. To create a 3D cube for each joint when ringAvatar is initialized, we simply do this:</p><p><pre class="brush: csharp">
private readonly List&lt;WPF3DModel&gt; _models = new List&lt;WPF3DModel&gt;();
private void CreateViewportModels()
{           
    for (int i = 0; i &lt; 20; i&#43;&#43;)
    { 
        WPF3DModel model = new WPF3DModel(&quot;mesh_cube&quot;);
        viewportModelsContainer2.Children.Add(model);

        // ...

        _models.Add(model);
    }

    // ...
}
</pre></p><p>And then each time we need to redraw the skeleton, we loop through the skeleton data and set the cube position like so:</p><p><pre class="brush: csharp">
if (SkeletonProcessor.RawSkeleton.TrackingState == SkeletonTrackingState.Tracked)
{
    int i = 0;  

    foreach (Joint joint in SkeletonProcessor.RawSkeleton.Joints)
    {
        if (joint.TrackingState == JointTrackingState.Tracked)
        {
                                        
            _models[i].Translate(                                        
                joint.Position.X * 8.0,                                    
                joint.Position.Y * 10.0,
                joint.Position.Z * -10.0);

            i&#43;&#43;;
        }
    }

    // ...

}
</pre></p><p>There are a few other areas in the User Console that you may want to further dig into, including the weighting for handling a punch as well dynamically generating arcs based on the position of the fist to the shoulder. However, for this experience, the User Console serves as a secondary display to support the playing experience and gives both the player and audience a visual anchor for the game.</p><h3>Making a 700lb Tank Drive like a First Person Shooter</h3><p>The character in a first person shooter (FPS) video game has an X position, a Y position, and a rotation vector. On an Xbox controller, the left stick controls the X,Y position. Y is the throttle (forward and backward), X is the strafing amount (left and right), and the right thumb stick moves the camera to change what you're looking at (rotation).&nbsp; When all three are combined, the character can do things such as run around someone while looking at them.</p><p>In the prior project, we had existing code that worked for controlling all 4 motors at the same time, working much like a tank does, so we only had throttle (forward and back) and strafing (left and right). Accordingly, we can move the motors in all directions, but there are still scenarios in which the wheels fight one another and the base won't move. By moving to a FPS style, we eliminate the ability to move the wheels in an non-productive way and actually make it a lot easier to drive.</p><p>Note that Clint had some wiring &quot;quirks&quot; with polarity and which motor was left VS right, he had to correct in these quirks in software <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' />:</p><p><pre class="brush: csharp">
public Speed CalculateSpeed(double throttleVector, double strafeVector, double rotationAngle)
{
    rotationAngle = VerifyLegalValues(rotationAngle);
    rotationAngle = AdjustValueForDeadzone(rotationAngle, AllowedRotationAngle, _negatedAllowedRotationAngle);

    // flipped wiring, easy fix is here  
    throttleVector *= -1;
    rotationAngle *= -1;
    
    // miss wired, had to flip throttle and straff for calc
    return CalculateSpeed(strafeVector &#43; rotationAngle, throttleVector, strafeVector - rotationAngle, throttleVector);
}

protected Speed CalculateSpeed(double leftSideThrottle, double leftSideVectorMultiplier, double rightSideThrottle, double rightSideVectorMultiplier) 
{ /* code from Jellybean */ }
</pre></p><h2>Conclusion</h2><p>The Boxing Bots project was one of the biggest things we have built to date. It was also one of our most successful projects. Though it was a rainy, cold day and night in Austin when the bots were revealed, and we had to move locations several times during setup to ensure the bots and computers wouldn't be fried by the rain, they ran flawlessly for the entire event and contestants seemed to have a lot of fun driving them.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0302%5B5%5D.jpg"><img title="IMG_0302" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0302_thumb%5B2%5D.jpg" alt="IMG_0302" width="500" height="375" border="0"></a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:247dcab61560403d8e5da04e01521034">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Boxing-Bots-An-Overview</comments>
      <itunes:summary>IntroductionIn early January, we were tasked with creating a unique, interactive experience for the SXSW Interactive launch party with Frog Design. We bounced around many ideas, and finally settled on a project that Rick suggested during our first meeting: boxing robots controlled via Kinect. The theme of the opening party was Retro Gaming, so we figured creating a life size version of a classic tabletop boxing game mashed up with a &amp;quot;Real Steel&amp;quot;-inspired Kinect experience would be a perfect fit. Most importantly, since this was going to be the first big project of the new Coding4Fun team, we wanted to push ourselves to create an experience that needed each of us to bring our unique blend of hardware, software, and interaction magic to the table under an aggressively tight deadline. HardwareThe BoxingBots had to be fit a few requirements: They had to be fun They had to survive for 4 hours, the length of the SXSW opening party Each robot had to punch for 90 seconds at a time, the length of a round They had to be life-size They had to be Kinect-drivable They had to be built, shipped, and reassembled for SXSW Creating a robot that could be beaten up for 4 hours and still work proved to be an interesting problem. After doing some research on different configurations and styles, it was decided we should leverage a prior project to get a jump start to meet the deadline. We repurposed sections of our Kinect drivable lounge chair, Jellybean! This was an advantage because it contained many known items, such as the motors, motor controllers, and chassis material.&amp;nbsp; Additionally, it was strong and fast, it was modular, and the code to drive it was already written. Jellybean would only get us part of the way there, however.&amp;nbsp; We also had to do some retrofitting to get it to work for our new project. The footprint of the base needed to shrink from 32x50 inches to 32x35 inches, while still allowing space to contain all of the original batteries, wheels, motors, m</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Boxing-Bots-An-Overview</link>
      <pubDate>Thu, 04 Oct 2012 21:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Boxing-Bots-An-Overview</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/959a6e59-5e5d-4824-aff5-01cc0ea75b19.png" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/ecb530a9-ffa6-418d-a3e1-96fec970031b.png" height="165" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/48e5dab5-8103-4fc6-a3a6-9bd49223e294.jpg" height="288" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez, Rick Barraza</itunes:author>
      <slash:comments>10</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Boxing-Bots-An-Overview/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>Kinect</category>
      <category>WPF</category>
      <category>Phidgets</category>
    </item>
  <item>
      <title>Features and Contracts in Windows Store Apps</title>
      <description><![CDATA[<p>&nbsp;</p><p>While the goal of these quickstarts is to discuss the issues and solutions involved in porting our Windows Phone 7 app to a Windows&nbsp;Store app, there are some features and requirements in Windows 8 we wanted to address: snapping and appcontracts.</p><p>Windows 8 Contracts provide OS level functionality and can significantly extend the power of your app when implemented properly. In this video, we will look at two contracts we implemented, the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868180.aspx"><strong>Search Contract</strong></a> and the <strong>Share Contract</strong>. But first, let us look at how snapping is handled in a Windows&nbsp;Store app.</p><p>&nbsp;</p><h1><strong>Handling Window Snapping</strong></h1><p>As we discussed in the last Quickstart, snapping can have a significant impact on how you choose to present your app interface. In a typical template project page, we will find a GridView and ListView element both positioned in <strong>Grid.Row=&quot;1&quot;</strong> under the navigation and page header row of our root grid.</p><p><img title="clip_image001" src="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/clip_image001%5B5%5D.png" alt="clip_image001" width="678" height="655" border="0"></p><p>It is the <strong>VisualStateManager</strong> that controls the visibility of these elements. Since <strong>PageHub.xaml</strong> inherits from&nbsp; <strong>Common\LayoutAwarePage.cs</strong>, we already have the orientation and positioning handlers taken care of. When the app is &quot;snapped&quot; to the screen and has its visual footprint significantly reduced, the <strong>VisualStateManager</strong> will toggle the visibility of the main <strong>GridView</strong> to <strong>Collapsed</strong> while making the thinner <strong>ListView</strong> based interface visible as shown below:</p><p><img title="clip_image002" src="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/clip_image002%5B3%5D-3.png" alt="clip_image002" width="691" height="621" border="0"></p><p>One other thing to note in this discussion is that while the <strong>ListView</strong> and <strong>GridView</strong> are both showing the same data, they would most likely need to reference different data templates and styles.</p><p>In the Khan Academy app, the <strong>ListView</strong> control that handles the snapped layout shares the same <strong>CollectionViewSource</strong> as the larger <strong>GridView</strong> control, but points to its own <strong>ItemTemplateSelector</strong> so that it will pull in the snapped styles accordingly.</p><p><img title="clip_image003" src="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/clip_image003%5B3%5D-4.png" alt="clip_image003" width="713" height="639" border="0"></p><p>&nbsp;</p><h1><strong>The Search Contract</strong></h1><p>The Search Contract allows your app to register with the operating system as being searchable from the Windows 8 Search charm.</p><p>&nbsp;</p><p><a href="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/image2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/image_thumb.png" alt="image" width="600" height="222" border="0"></a></p><p>&nbsp;</p><p>To set this up, we need to add some code to the <strong>LaunchApp()</strong> method in <strong>App.xaml.cs</strong> as shown below:</p><p><strong>App.xaml.cs</strong></p><p><pre class="brush: csharp">
public async void LaunchApp(
    ApplicationExecutionState previousExecutionState)
{
    DataSource = new KhanDataSource();
    await DataSource.LoadAllData();
 
    SearchPane searchPane = SearchPane.GetForCurrentView();
    searchPane.PlaceholderText = “Search Khan Academy”;
    searchPane.QuerySubmitted &#43;=
        (sender, queryArgs) =&gt;
        {
            KhanAcademy.SearchResultsPage.Activate(
                queryArgs.QueryText, previousExecutionState);
        };
        […]
</pre></p><p>&nbsp;</p><p>First, we get the <strong>SearchPane</strong> object for the current app. Once we have a handle to the instance of the pane, we can set some properties to make the search experience a bit more tailored to our app. Namely, we set the <strong>PlaceholderText</strong> property to the string “Search Khan Academy”. Finally, we hook the <strong>QuerySubmitted</strong> event off the <strong>SearchPane</strong> object, which will be called once the user presses the Enter key or clicks/taps the magnifying glass icon to the right of the search box. In the event handler, the <strong>SearchResultsPage</strong> is activated and displayed with the user’s query text passed to the page.</p><p>The Search pane can also handle real-time suggestions based on the query the user is typing. To do this, we just need to handle the <strong>SuggestionsRequested</strong> and <strong>ResultSuggestionChosen</strong> events as shown:</p><p><strong>C#</strong></p><p><pre class="brush: csharp">
            searchPane.SuggestionsRequested &#43;= 
                (sender, suggestionArgs) =&gt;
                {
                    var videos = App.DataSource.TopicGroups.SelectMany(g =&gt;
                        g.Playlists.SelectMany(p =&gt; p.Videos.Where(v =&gt;
                            Regex.IsMatch(v.Name ?? &quot;&quot;, suggestionArgs.QueryText, RegexOptions.IgnoreCase) ||
                            Regex.IsMatch(v.Description ?? &quot;&quot;, suggestionArgs.QueryText, RegexOptions.IgnoreCase))))
                            .Distinct(VideoItem.CreateComparer())
                            .Take(3);
                    foreach(VideoItem vi in videos)
                        suggestionArgs.Request.SearchSuggestionCollection.AppendQuerySuggestion(vi.Title);
                    var recommended = App.DataSource.TopicGroups.SelectMany(g =&gt;
                        g.Playlists.SelectMany(p =&gt; p.Videos.Where(v =&gt;
                            Regex.IsMatch(v.Name ?? &quot;&quot;, suggestionArgs.QueryText, RegexOptions.IgnoreCase)))).FirstOrDefault();
                    if(recommended != null)
                    {
                        suggestionArgs.Request.SearchSuggestionCollection.AppendSearchSeparator(&quot;Recommended&quot;);
                        IRandomAccessStreamReference imgStream = RandomAccessStreamReference.CreateFromUri(recommended.ImagePath);
                        suggestionArgs.Request.SearchSuggestionCollection.AppendResultSuggestion(recommended.Title, recommended.Description, recommended.VideoPath.ToString(), imgStream, recommended.Title);
                    }
                };
            searchPane.ResultSuggestionChosen &#43;=
                (sender, resultArgs) =&gt;
                {
                    var recommended = App.DataSource.TopicGroups.SelectMany(g =&gt;
                        g.Playlists.SelectMany(p =&gt; p.Videos.Where(v =&gt;
                            Regex.IsMatch(v.VideoPath.ToString() ?? &quot;&quot;, resultArgs.Tag, RegexOptions.IgnoreCase)))).FirstOrDefault();
                    Frame f = Window.Current.Content as Frame;
                    f.Navigate(typeof(VideoPage), JsonSerializer.Serialize(recommended));
                };
</pre></p><p>&nbsp;</p><p>In the <strong>SuggestionRequested</strong> event handler, we use a LINQ query to find the first 3 results that match what the user is typing and add them to the suggestions list using the <strong>AppendQuerySuggestion</strong> method off the <strong>SearchSuggestionCollection</strong> object. In addition, we also use LINQ to find the closest match to what the user is typing to display and display that after a line separator.</p><p>The line gets added with the <strong>AppendSearchSeparator</strong> method, and the single result gets added with the <strong>AppendResultSuggestion</strong> method. The specific result suggestion can include an icon, and we get the stream for that icon using the <strong>CreateFromUri</strong> method off the <strong>RandomAccessStreamReference</strong> object, passing in the path to the image we want to use as the icon. This returns the <strong>IRandomAccessStreamReference</strong> required by the <strong>AppendResultSuggestion</strong> method.</p><p>In the <strong>ResultSuggestionChosen</strong> method, we determine which suggestion the user selected and then navigate to the <strong>VideoPage</strong> to show the video to the user.</p><p>&nbsp;</p><h1><strong>The Share and Devices Contracts</strong></h1><p>The <strong>Share Contract</strong> allows the user to share a piece of data from the current app to another app which knows how to receive the data. For our app, we wanted to allow the user to share a link to the video they are watching to other apps. This works great with the Windows 8 mail app.</p><p>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/image5.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/b99a24a9f48a4ce2b672a09b015ae985/image_thumb1.png" alt="image" width="600" height="338" border="0"></a></p><p>&nbsp;</p><p>To accomplish this, we override the <strong>DataRequested</strong> method on the <strong>VideoPage</strong> class as shown:</p><p><strong>VideoPage.xaml.cs</strong></p><p><pre class="brush: csharp">
public sealed partial class VideoPage
    : KhanAcademy.Common.LayoutAwarePage
{
    private PlayToManager _playToManager = null;
    private CoreDispatcher _dispatcher = null;
    private DisplayRequest _displayRequest = null;
 
    public VideoPage()
    {
        this.InitializeComponent();
    }
    protected override void DataRequested(
        DataTransferManager sender,
        DataRequestedEventArgs args)
    {
        VideoItem vi = (this.DataContext as VideoItem);
        args.Request.Data.Properties.Title = vi.Name;
        args.Request.Data.Properties.Description = vi.Description;
        args.Request.Data.SetUri(vi.KhanPath);
    }
</pre></p><p>In this method, we get the <strong>VideoItem</strong> that is currently being played, and use its properties to fill out the Data object property of the Request object. The <strong>SetUri</strong> method is used to pass the actual Uri to the Khan Academy website.</p><p>Finally, we wanted to enable <strong>PlayTo</strong> functionality so the user can quickly and easily send the video output to a TV or other media device on the network. The user can choose to do this while watching the video by selecting the <strong>Devices charm</strong>. Any PlayTo-enabled devices on the network will show up in this device list.</p><p>In code, we handle this scenario in the <strong>OnNavigatedTo</strong> and <strong>OnNavigatedFrom</strong> overridden methods.</p><p><strong>VideoPage.xaml.cs</strong></p><p><pre class="brush: csharp">
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    _dispatcher = Window.Current.CoreWindow.Dispatcher;
    _playToManager = PlayToManager.GetForCurrentView();
    _playToManager.SourceRequested &#43;= playToManager_SourceRequested;
    if(_displayRequest == null)
        _displayRequest = new DisplayRequest();
    _displayRequest.RequestActive();
    base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    _playToManager.SourceRequested -= playToManager_SourceRequested;
    if(_displayRequest != null)
        _displayRequest.RequestRelease();
    base.OnNavigatedFrom(e);
}
void playToManager_SourceRequested(PlayToManager sender, PlayToSourceRequestedEventArgs args)
{
    var deferral = args.SourceRequest.GetDeferral();
    var handler = _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =&gt;
    {
        args.SourceRequest.SetSource(videoElement.PlayToSource);
        deferral.Complete();
    });
}
</pre></p><p>In the <strong>OnNavigatedTo</strong> method, we get an instance of the <strong>PlayToManager</strong> and hook the <strong>SourceRequested</strong> event. We also grab an instance of the current Dispatcher. In the <strong>SourceRequested</strong> event handler, we request a deferral. This tells the PlayTo manager to wait until we give it the PlayTo source so the request doesn’t time out. We then, using the dispatcher, set the source of the PlayTo request to the video player’s <strong>PlayToSource</strong> property, and then complete the deferral. At this point, the PlayTo request is sent and the media player talks to the OS to make the magic happen. Note that in the <strong>OnNavigatedFrom</strong> method we unhook the <strong>SourceRequested</strong> event handler since it is no longer needed once the user navigates away from this page.</p><p>So at this point, we have come up with a migration strategy for porting our Windows Phone 8 to Windows 8, handled changes to how we handle asynchronous data requests and have a well styled, data bound interface that leverages the newest features of Windows 8. From here, the next step would be submitting to the store for distribution.</p><p>Hopefully, this set of quickstarts has covered some key areas of interest in getting your app up and running on Windows 8.</p><p>I would like to extend a tremendous amount of gratitude for Joel Martinez and all his tireless work as well as opening up the <strong><em>Viewer for Khan Academy</em></strong> app to serve as a Coding4Fun Community project here on Channel 9.</p><p>The source code for the Windows 8 Khan Academy app is available for <a href="https://github.com/joelmartinez/Khan-Academy-for-WinRT">download</a>:</p><p>&nbsp;</p><p>If you have any questions, comments, or feedback feel free to join in the discussion.</p><p>Twitter: @<a href="http://twitter.com/rickbarraza">rickbarraza</a>, <a href="http://twitter.com/joelmartinez">@joelmartinez</a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ea258cf458514bb2b1b5a0a00157701d">]]></description>
      <comments>http://channel9.msdn.com/Series/Migrating-apps-from-Windows-Phone-to-Windows-8/Features-and-Contracts-in-Windows-Store-Apps</comments>
      <itunes:summary>&amp;nbsp; While the goal of these quickstarts is to discuss the issues and solutions involved in porting our Windows Phone 7 app to a Windows&amp;nbsp;Store app, there are some features and requirements in Windows 8 we wanted to address: snapping and appcontracts. Windows 8 Contracts provide OS level functionality and can significantly extend the power of your app when implemented properly. In this video, we will look at two contracts we implemented, the Search Contract and the Share Contract. But first, let us look at how snapping is handled in a Windows&amp;nbsp;Store app. &amp;nbsp; Handling Window SnappingAs we discussed in the last Quickstart, snapping can have a significant impact on how you choose to present your app interface. In a typical template project page, we will find a GridView and ListView element both positioned in Grid.Row=&amp;quot;1&amp;quot; under the navigation and page header row of our root grid.  It is the VisualStateManager that controls the visibility of these elements. Since PageHub.xaml inherits from&amp;nbsp; Common\LayoutAwarePage.cs, we already have the orientation and positioning handlers taken care of. When the app is &amp;quot;snapped&amp;quot; to the screen and has its visual footprint significantly reduced, the VisualStateManager will toggle the visibility of the main GridView to Collapsed while making the thinner ListView based interface visible as shown below:  One other thing to note in this discussion is that while the ListView and GridView are both showing the same data, they would most likely need to reference different data templates and styles. In the Khan Academy app, the ListView control that handles the snapped layout shares the same CollectionViewSource as the larger GridView control, but points to its own ItemTemplateSelector so that it will pull in the snapped styles accordingly.  &amp;nbsp; The Search ContractThe Search Contract allows your app to register with the operating system as being searchable from the Windows 8 Search charm. &amp;nbsp;  &amp;nbsp; To </itunes:summary>
      <itunes:duration>881</itunes:duration>
      <link>http://channel9.msdn.com/Series/Migrating-apps-from-Windows-Phone-to-Windows-8/Features-and-Contracts-in-Windows-Store-Apps</link>
      <pubDate>Wed, 26 Sep 2012 19:53:32 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Series/Migrating-apps-from-Windows-Phone-to-Windows-8/Features-and-Contracts-in-Windows-Store-Apps</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.mp3" expression="full" duration="881" fileSize="14099628" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.mp4" expression="full" duration="881" fileSize="83158376" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.webm" expression="full" duration="881" fileSize="31151308" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.wma" expression="full" duration="881" fileSize="7130519" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.wmv" expression="full" duration="881" fileSize="46701173" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05_high.mp4" expression="full" duration="881" fileSize="182437332" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05_mid.mp4" expression="full" duration="881" fileSize="127445509" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05_Source.wmv" expression="full" duration="881" fileSize="113621308" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.ism/manifest" expression="full" duration="881" fileSize="6076" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/ae72/4454b2eb-7567-4803-8c31-ff4797c1ae72/Phone7toWin8QS05.wmv" length="46701173" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Rick Barraza</dc:creator>
      <itunes:author>Brian Peek, Rick Barraza</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Series/Migrating-apps-from-Windows-Phone-to-Windows-8/Features-and-Contracts-in-Windows-Store-Apps/RSS</wfw:commentRss>
      <category>Windows Phone</category>
      <category>Windows Store App</category>
      <category>Microsoft Design Style</category>
      <category>WindowsContent</category>
    </item>
  <item>
      <title>Code Snippets for Windows Store Apps</title>
      <description><![CDATA[<p>In partnership with the Visual Studio team, we are launching <a href="http://windows8snippets.codeplex.com">Code Snippets for Windows Store apps</a>, a collection of around 60 IntelliSense Code Snippets for common Windows Store app programming tasks. The snippets are available for Visual Basic, C#, C&#43;&#43;, and JavaScript developers.</p><p>For example, if you don’t know how to <strong>copy a file</strong> in JavaScript or C&#43;&#43;, just right-click, select <strong>Insert Snippet</strong>, select the code snippet, and it will automatically add the code to your Windows app as shown in the screenshots below.</p><h2>Download It</h2><p><a class="big download button" href="https://windows8snippets.codeplex.com/releases/view/94130">Download Now</a></p><p>&nbsp;</p><p>Please see the following pages to learn how to install the snippets and how to use them.</p><ul><li><a href="https://windows8snippets.codeplex.com/wikipage?title=Installation&amp;referringTitle=Documentation">Installation</a> </li><li><a href="https://windows8snippets.codeplex.com/wikipage?title=List%20of%20Snippets&amp;referringTitle=Documentation">See the full list of Snippets</a> </li></ul><p>&nbsp;</p><h2>Screenshots</h2><p>After installing, right-click and select Insert Snippet...and select the snippet from the list. Then press Tab to jump between fields.</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/8d7ea90af97f412b9d0f9de900cd4ab4/image_thumb.png" alt="image" width="661" height="585" border="0"></p><p>&nbsp;</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/8d7ea90af97f412b9d0f9de900cd4ab4/image_thumb%5B4%5D.png" alt="image" width="658" height="603" border="0"></p><p>&nbsp;</p><h2>Feedback</h2><p>Give them a try and <a href="https://windows8snippets.codeplex.com/discussions">let us know what you think</a>!</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:bda6d5a2c05e4eb59581a0c900128c6c">]]></description>
      <comments>http://channel9.msdn.com/Blogs/C9Team/Code-Snippets-for-Windows-Store-Apps</comments>
      <itunes:summary>In partnership with the Visual Studio team, we are launching Code Snippets for Windows Store apps, a collection of around 60 IntelliSense Code Snippets for common Windows Store app programming tasks. The snippets are available for Visual Basic, C#, C&amp;#43;&amp;#43;, and JavaScript developers. For example, if you don’t know how to copy a file in JavaScript or C&amp;#43;&amp;#43;, just right-click, select Insert Snippet, select the code snippet, and it will automatically add the code to your Windows app as shown in the screenshots below. Download ItDownload Now &amp;nbsp; Please see the following pages to learn how to install the snippets and how to use them. Installation See the full list of Snippets &amp;nbsp; ScreenshotsAfter installing, right-click and select Insert Snippet...and select the snippet from the list. Then press Tab to jump between fields.  &amp;nbsp;  &amp;nbsp; FeedbackGive them a try and let us know what you think! </itunes:summary>
      <link>http://channel9.msdn.com/Blogs/C9Team/Code-Snippets-for-Windows-Store-Apps</link>
      <pubDate>Tue, 11 Sep 2012 19:01:50 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/C9Team/Code-Snippets-for-Windows-Store-Apps</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/4fe9abe5-e5f8-40ec-a95b-d3a29a5324d8.png" height="100" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/1ad42d77-b430-4bcc-98ea-162666797d0e.png" height="220" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/31dc0ae0-77b1-4027-bf5f-21a2f61f0c29.png" height="288" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Paul van Brenk</dc:creator>
      <itunes:author>Brian Peek, Paul van Brenk</itunes:author>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/C9Team/Code-Snippets-for-Windows-Store-Apps/RSS</wfw:commentRss>
      <category>Windows 8</category>
      <category>Visual Studio 2012</category>
    </item>
  <item>
      <title>TWC9: Build sold out, Portable Class Library, eBooks galore, SQLite, WinRT and more</title>
      <description><![CDATA[<p>This week on Channel 9, Dan and Brian Peek discuss the week's top developer news, including:</p><ul><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=51s">[0:51]</a>&nbsp;<a href="http://www.buildwindows.com/">http://www.buildwindows.com/</a>, <a href="http://channel9.msdn.com/Blogs/C9Team/Build-2012-Registration-is-now-open">Build 2012 is sold out. Tune in online.</a>, <a href="http://channel9.msdn.com/Events/BUILD/2012">http://channel9.msdn.com/Events/BUILD/2012</a> </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=1m50s">[1:50]</a> <a href="http://kishore1021.wordpress.com/2012/08/06/what-is-portable-class-library-project-in-visual-studio-2012-net-4-5/">What is Portable Class Library project in Visual Studio 2012– .NET 4.5</a> (Kishore Babu Gaddam) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=3m4s">[3:04]</a> <a href="http://channel9.msdn.com/Series/Javascript-Fundamentals-Development-for-Absolute-Beginners">Javascript Fundamentals: Development for Absolute Beginners</a> (Clint Rutkas, Bob Tabor, Golnaz ) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=3m54s">[3:54]</a> <a href="http://blogs.msdn.com/b/windowsappdev/archive/2012/08/06/building-your-own-windows-runtime-components-to-deliver-great-metro-style-apps.aspx">Building your own Windows Runtime components to deliver great Metro style apps</a> (Ines Khelifi) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=6m22s">[6:22]</a> <a href="http://timheuer.com/blog/archive/2012/08/07/updated-how-to-using-sqlite-from-windows-store-apps.aspx">UPDATED HOWTO: SQLite with Windows 8 apps</a> (Tim Heuer) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=7m34s">[7:34]</a> <a href="http://alnurismail.com/maximizing-code-reuse-across-windows-8-and-windows-phone-apps/">Maximizing Code Reuse Across Windows 8 and Windows Phone Apps</a> (Alnur Ismail) </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=8m37s">[8:37]</a> <a href="http://visualstudiogallery.msdn.microsoft.com/0526563b-7a48-4b17-a087-a35cea701052">Callisto</a> (Tim Heuer) [Found via: <a href="http://blogs.technet.com/b/kennymaita/archive/2012/08/07/callisto-library.aspx">CALLISTO Library</a>] </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=9m39s">[9:39]</a> <a href="http://blogs.msdn.com/b/mssmallbiz/archive/2012/07/27/large-collection-of-free-microsoft-ebooks-for-you-including-sharepoint-visual-studio-windows-phone-windows-8-office-365-office-2010-sql-server-2012-azure-and-more.aspx">Large collection of Free Microsoft eBooks for you, including: SharePoint, Visual Studio, Windows Phone, Windows 8, Office 365, Office 2010, SQL Server 2012, Azure, and more.</a> , <a href="http://blogs.msdn.com/b/mssmallbiz/archive/2012/07/30/another-large-collection-of-free-microsoft-ebooks-and-resource-kits-for-you-including-sharepoint-2013-office-2013-office-365-duet-2-0-azure-cloud-windows-phone-lync-dynamics-crm-and-more.aspx?wa=wsignin1.0">Another large collection of Free Microsoft eBooks and Resource Kits for you, including: SharePoint 2013, Office 2013, Office 365, Duet 2.0, Azure, Cloud, Windows Phone, Lync, Dynamics CRM, and more.</a> (Eric Ligman), <a href="http://coolthingoftheday.blogspot.com/2012/06/microsoft-technologies-e-book-gallery.html">Microsoft Technologies E-Book Gallery (TechNet Wiki)</a> </li><li><a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=10m32s">[10:32]</a> Channel 9 Highlight: <a href="http://channel9.msdn.com/Shows/Defrag-Tools">Defrag Tools</a> (Andrew Richards, Larry Larsen) </li></ul><p><strong>Picks of the Week!</strong></p><ul><li>Brian's Pick of the Week:<a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=11m21s">[11:21]</a>&nbsp;<a href="http://blogs.technet.com/b/next/archive/2012/08/07/kin-202-tre-animating-the-world-with-the-human-body.aspx" target="_blank">KinÊtre - Animating the World with the Human Body</a> (Steve Clayton) </li><li>Dan's Pick of the Week: <a href="http://channel9.msdn.com/Shows/This&#43;Week&#43;On&#43;Channel&#43;9/TWC9-August-10-2012#time=12m58s">[12:58]</a> Build Easter Egg <a href="http://www.buildwindows.com">http://www.buildwindows.com</a>&nbsp; </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:a25fa9cd387b4a2ba935a0a8013d10fb">]]></description>
      <comments>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-August-10-2012</comments>
      <itunes:summary>This week on Channel 9, Dan and Brian Peek discuss the week&#39;s top developer news, including: [0:51]&amp;nbsp;http://www.buildwindows.com/, Build 2012 is sold out. Tune in online., http://channel9.msdn.com/Events/BUILD/2012 [1:50] What is Portable Class Library project in Visual Studio 2012– .NET 4.5 (Kishore Babu Gaddam) [3:04] Javascript Fundamentals: Development for Absolute Beginners (Clint Rutkas, Bob Tabor, Golnaz ) [3:54] Building your own Windows Runtime components to deliver great Metro style apps (Ines Khelifi) [6:22] UPDATED HOWTO: SQLite with Windows 8 apps (Tim Heuer) [7:34] Maximizing Code Reuse Across Windows 8 and Windows Phone Apps (Alnur Ismail) [8:37] Callisto (Tim Heuer) [Found via: CALLISTO Library] [9:39] Large collection of Free Microsoft eBooks for you, including: SharePoint, Visual Studio, Windows Phone, Windows 8, Office 365, Office 2010, SQL Server 2012, Azure, and more. , Another large collection of Free Microsoft eBooks and Resource Kits for you, including: SharePoint 2013, Office 2013, Office 365, Duet 2.0, Azure, Cloud, Windows Phone, Lync, Dynamics CRM, and more. (Eric Ligman), Microsoft Technologies E-Book Gallery (TechNet Wiki) [10:32] Channel 9 Highlight: Defrag Tools (Andrew Richards, Larry Larsen) Picks of the Week! Brian&#39;s Pick of the Week:[11:21]&amp;nbsp;Kin&#202;tre - Animating the World with the Human Body (Steve Clayton) Dan&#39;s Pick of the Week: [12:58] Build Easter Egg http://www.buildwindows.com&amp;nbsp; </itunes:summary>
      <itunes:duration>887</itunes:duration>
      <link>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-August-10-2012</link>
      <pubDate>Sat, 11 Aug 2012 02:20:03 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-August-10-2012</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012_512.jpg" height="288" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.mp3" expression="full" duration="887" fileSize="14205598" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.mp4" expression="full" duration="887" fileSize="85041416" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.webm" expression="full" duration="887" fileSize="32239917" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.wma" expression="full" duration="887" fileSize="7184591" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.wmv" expression="full" duration="887" fileSize="56352455" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012_high.mp4" expression="full" duration="887" fileSize="186035618" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012_mid.mp4" expression="full" duration="887" fileSize="130062717" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012_Source.wmv" expression="full" duration="887" fileSize="159206586" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.ism/manifest" expression="full" duration="887" fileSize="6076" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/9925/0f98ace3-ffd8-422b-b482-cb0800829925/TWC9August102012.wmv" length="56352455" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Dan Fernandez, Greg Duncan</dc:creator>
      <itunes:author>Brian Peek, Dan Fernandez, Greg Duncan</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-August-10-2012/RSS</wfw:commentRss>
      <category>JavaScript</category>
      <category>Kinect</category>
      <category>visua studio</category>
      <category>Build</category>
      <category>Windows 8</category>
      <category>WinRT</category>
    </item>
  <item>
      <title>What Is an Arduino Shield and Why Should My Netduino Care?</title>
      <description><![CDATA[<p><strong>C9 Netduino Shield Series - Using Arduino Shield with Netduino - Part I</strong> </p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001_thumb1%5B2%5D.jpg"><img title="clip_image001_thumb1" border="0" alt="clip_image001_thumb1" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001_thumb1_thumb.jpg" width="236" height="240"></a>&nbsp;<br>Photo courtesy of <a href="http://tronixstuff.wordpress.com/">John Boxall</a> </p><h3>Introduction</h3><p>When the <a href="http://www.arduino.cc/en/Guide/Introduction">Arduino</a> Duemilanove microcontroller appeared in 2005, it featured a set of female pin headers exposing most of the pins of the ATmega168 for easy hacking and for connecting accessory boards known as 'Shields'. The purpose of a shield is to provide new plug-and-play functionality to the host microcontroller, such as circuit prototyping, motion control, sensor integration, network and radio communication, or gaming interfaces, without worrying too much about the hardware implementation details. Seven years after the birth of the original Arduino, new shields keep coming out and are being cataloged on <a href="http://shieldlist.org/">http://shieldlist.org/</a>, a testament to the versatility of the design. It is also simple to build a DIY shield when nothing out there will meet your needs or when you want to understand how the shield concept works from the ground up. </p><p>In their infinite wisdom, Secret Labs, the makers of the <a href="http://www.netduino.com/">Netduino</a>, adopted the same Arduino form factor and header pin out to let .NET Micro Framework users tap into the vast array of Arduino shields on the market. Yet, there's always one hurdle that needs to be overcome: in order to give access to their hardware functions easily, many Arduino shields provide <a href="http://www.arduino.cc/playground/Main/GeneralCodeLibrary">sample sketches</a> (a.k.a. C/C&#43;&#43; <a href="http://wiring.org.co/">Wiring programs</a>) and <a href="http://arduino.cc/en/Reference/Libraries">libraries</a> also <a href="http://arduino.cc/en/Reference/HomePage">written in C/C&#43;&#43;</a> designed to be used within the <a href="http://arduino.cc/en/Guide/Windows#toc6">Arduino IDE</a>. Unfortunately, Arduino sketches and libraries aren't compatible with the Visual Studio environment and the .NET runtime: they need to be adapted in order to make use of the shield's hardware. </p><p>The goal of this series of articles is to attempt to demystify what an Arduino shield is. To do this, we'll start by building one from scratch. Then, we'll present a generic approach for selecting Netduino-compatible Arduino shields and adapting Arduino code to interface with the .NET Micro Framework. </p><h5>Selecting Arduino shields for use with Netduino / Plus</h5><p>Arduino shields using hardware components interfaced over protocols such as <a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus">SPI</a>, <a href="http://www.i2c-bus.org/">I2C</a>, <a href="http://www.maxim-ic.com/products/1-wire/flash/overview/index.cfm">1-Wire</a> or serially over a <a href="http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter">UART</a> are generally good candidates for a Netduino adaptation because the .NET Micro Framework supports these protocols natively and can do bulk I/O transfers, yielding good performance. </p><p>However, if a shield requires <a href="http://en.wikipedia.org/wiki/Bit_banging">bit-banging</a> data on GPIOs (i.e. communicating data serially, such as SPI, I2C, RS-232, in software by toggling GPIO lines individually instead of using dedicated hardware interfaces) or has very low I/O latency requirements, it may not be practical or even possible to use the shield on a Netduino / Plus. </p><p>The reason for this is simple: the Arduino runs native code and can access hardware registers directly with a latency orders of magnitude lower than what the .NET Micro Framework can achieve on a Netduino / Plus where toggling GPIOs means going through multiple framework layers while running interpreted code. The maximum raw I/O toggling frequency on a Netduino / Plus clocked at 48 MHz <a href="http://fabienroyer.wordpress.com/2011/01/22/netduino-gpio-speed-test/">was measured around ~8.4KHz</a> which is slow compared to the few MHz achievable on an Arduino clocked at 16 MHz. </p><p>Fortunately, there are possible workarounds and strategies </p><ul><li>Whenever an Arduino library bit-bangs SPI data on GPIOs, regardless of the pins used to do it, it can be replaced by using the standard SPI interface on the Netduino / Plus. </li><li>The Netduino / Plus has significantly more RAM available than the Arduino and can transfer larger SPI data buffer in a single shot, dramatically reducing I/O latency. For instance, <a href="http://fabienroyer.wordpress.com/2011/09/14/driving-an-adafruit-st7565-negative-lcd-display-with-a-netduino/">driving a display shield would greatly benefit from this method</a> where a frame is cached in RAM on the Netduino / Plus then sent in one shot over SPI to the hardware display driver.</li></ul><p>The bottom line is that it is always a good idea to review how the Arduino code interfaces with a given shield before proceeding with a purchase or starting a conversion project. This review process is also facilitated by <a href="http://shieldlist.org/">http://shieldlist.org</a> which shows which pins are being used to drive a shield. For example, the <a href="http://shieldlist.org/adafruit/logger">Adafruit Industries Logger Shield</a> uses hardware SPI (pins D10-D13) for the SD card and I2C (pins A4-A5) for the DS1307 real time clock, making it a perfect adaptation candidate for the Netduino / Plus as we'll see in our next article.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B18%5D.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B8%5D-6.png" width="250" height="196"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B19%5D-2.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B9%5D-1.png" width="250" height="224"></a></p><p>It's also very important to know what features are available on the .NET Micro Framework running on the Netduino / Plus: some things come standard with the .NET Micro Framework which normally require add-ons libraries on the Arduino such as file system and networking support. </p><p>Finally, it is wise to search code repositories such as <a href="http://www.codeplex.com/">CodePlex</a>, <a href="https://bitbucket.org/">BitBucket</a> and <a href="https://github.com/">GitHub</a> for hardware drivers and libraries before undertaking writing one in C# from scratch based on component datasheets. This extends to the <a href="http://forums.netduino.com/index.php?/forum/15-project-showcase/">Netduino</a> and the <a href="http://www.tinyclr.com/forum">TinyCLR</a> community forums where many people have posted drivers in discussion threads. </p><h4>Building a shield from scratch to meet specific requirements</h4><p>Recently, we were asked if it was possible to connect our <a href="http://nwazet.com/touch-display-module">Touch Display module</a> designed for a <a href="http://www.netduino.com/netduinogo/specs.htm">Netduino Go!</a> to a <a href="http://www.netduino.com/netduino/specs.htm">Netduino</a> / <a href="http://www.netduino.com/netduinoplus/specs.htm">Plus</a>. By doing a bit of research and seeing how the driver for the Touch Module works, this can be done by building a simple custom shield composed of a few parts connecting the Netduino pin headers to a Netduino Go! socket breakout board like so: </p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/FinishedCustomShield%5B3%5D.jpg"><img title="FinishedCustomShield" border="0" alt="FinishedCustomShield" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/FinishedCustomShield_thumb%5B1%5D.jpg" width="250" height="166"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/GoTouchDisplayOnNetduino%5B3%5D.jpg"><img title="GoTouchDisplayOnNetduino" border="0" alt="GoTouchDisplayOnNetduino" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/GoTouchDisplayOnNetduino_thumb%5B1%5D.jpg" width="250" height="267"></a> </p><h5>High-Level Software Interface</h5><p>To frame the rest of this article, the communication interface with the shield is done using SPI and a GPIO used for synchronization. The communication protocol details are wrapped in the <i>Nwazet.Go.Display.Imaging.VirtualCanvas</i> class which needs to be initialized with the SPI and GPIO parameters matching the pin out of the shield: </p><pre><pre class="brush: csharp">
var canvas = new VirtualCanvas(TouchEventHandler, WidgetClickedHandler);

canvas.Initialize(
    displaySpi: SPI.SPI_module.SPI1,
    displayChipSelect: Pins.GPIO_PIN_D9,
    displayGPIO: Pins.GPIO_PIN_D8,
    speedKHz: 5000);
</pre>

</pre><p>From that point on, all interactions with the shield are done through <i>Draw*</i> methods followed by a call to the <i>Execute() </i>method which handles sending and receiving SPI data packets. The <i>VirtualCanvas</i> class also provides methods for creating widgets such as buttons, receiving touch screen events and setting the screen orientation. </p><p>For example, the following code snippet draws and updates a progress bar and uses one of the proportional fonts built into the display: </p><pre><pre class="brush: csharp">
public static void Main() {
    var canvas = new VirtualCanvas();
    canvas.Initialize(
        displaySpi: SPI.SPI_module.SPI1,
        displayChipSelect: Pins.GPIO_PIN_D9,
        displayGPIO: Pins.GPIO_PIN_D8,
        speedKHz: 5000);
    var fontInfo = new DejaVuSans9().GetFontInfo();
    canvas.DrawFill(0xFFFF);
    canvas.DrawString(5, 144, (ushort)BasicColor.Black, fontInfo.ID, &quot;Progress&quot;);
    for (var progress = 1; progress &lt;= 100; progress&#43;&#43;) {
        canvas.DrawProgressBar(
            70, 140,
            75, 12,
            RoundedCornerStyle.All,
            RoundedCornerStyle.All,
            (ushort)BasicColor.Black,
            (ushort)GrayScaleValues.Gray_128,
            (ushort)GrayScaleValues.Gray_30,
            (ushort)BasicColor.Green,
            progress);
        Thread.Sleep(100);
        canvas.Execute();
    }
}
</pre>

</pre><h5>Netduino Go! Socket Pin Out</h5><p>In order to build the shield, we need to start with mapping out the connections between the Go! bus socket and the header pins of the shield. </p><p>The Go! socket pin out was designed by Secret Labs to be compatible with <a href="http://gadgeteer.codeplex.com/releases/view/72208">Gadgeteer modules supporting the following socket types</a>: S (SPI), U (UART), X (3 GPIO) as documented in the <a href="http://gadgeteer.codeplex.com/downloads/get/273357">.NET Gadgeteer Mainboard Builder's Guide v 1.8, page 6</a>. This makes our little shield compatible with a Gadgeteer board as long as it is connected to an S socket. As far as other .NET Micro Framework boards are concerned, they should also work fine if they can drive an SPI slave device at 5 MHz, the minimum SPI clock frequency required by the Touch Display module. </p><p><b><i></i></b></p><h6>Gadgeteer Socket Types</h6><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B2%5D-3.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb-3.png" width="500" height="433"></a> </p><h6>Netduino Go! Socket</h6><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-5.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B1%5D-2.png" width="500" height="375"></a> </p><p>The <a href="http://www.netduino.com/netduino/specs.htm">hardware specifications of the Netduino</a> / Plus tells us that the Netduino GPIOs correspond exactly to the <a href="http://arduino.cc/en/Main/ArduinoBoardUno">Arduino Uno GPIOs</a>: </p><ul><li>digital pins 0-1: UART 1 RX, TX </li><li>digital pins 2-3: UART 2 RX, TX </li><li>digital pins 5-6: PWM, PWM </li><li>digital pins 7-8: UART 2 RTS, CTS </li><li>digital pins 9-10: PWM, PWM </li><li>digital pins 11-13: SPI MOSI, MISO, SPCK </li><li>analog pins 4-5: I2C SDA, SCL </li></ul><p>With this information, we can proceed with the creation of schematics to bridge the gap between the two worlds. </p><h5>Shield schematics</h5><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/What%20is%20a%20shield%20schematics%5B2%5D-1.png"><img title="What is a shield schematics" border="0" alt="What is a shield schematics" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/What%20is%20a%20shield%20schematics_thumb-1.png" width="500" height="350"></a> </p><h5>How does this custom shield work?</h5><p>The Netduino Go! bus is designed around the <a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus">SPI protocol</a> (see Go! socket pins 6-10) which the Netduino / Plus can speak easily, making a Netduino Go! module or a <a href="http://www.ghielectronics.com/catalog/category/275/">S-type Gadgeteer module</a> appear like any other SPI device to a Netduino / Plus. </p><p>You will notice that the following pins aren't connected on the Go! socket for the sake of simplification: </p><ul><li>Pin 2 (5v power): the Touch Display module operates on 3.3v, therefore the 5v power supply is not needed but could be connected to the 5v header of the Netduino to be fully compliant. </li><li>Pin 4 and 5 (UART): the Touch Display module does not make use of the serial interface during normal operation, so these lines can remain disconnected. However, to be fully compliant, Pin 4 (RX) and 5 (TX) on the Go! socket could be respectively connected to Netduino pin D1 (TX) and D0 (RX). </li><li>The fact that these lines aren't connected in this specific scenario would cause another module requiring a UART and/or 5v to not work obviously. </li></ul><p>While the SPI part is straight forward, there's a bit more to the Go! bus electrical specification that must be taken into account: the Netduino Go! bus also uses its GPIO pin on boot (see Go! socket pin 3) to control the behavior of modules based on ARM Cortex chips: when the GPIO pin is held HIGH on module power-up, the ARM Cortex chip enters its bootloader mode and waits to be flashed with new firmware over the Go! bus UART (see Go! socket pins 4-5). The ARM Cortex bootloader remains active until the ARM Cortex chip is reset or power-cycled. </p><p>This is important to know for two reasons: </p><ol><li>The Touch Display module is powered by an ARM Cortex M3 chip. </li><li>On boot, a Netduino / Plus sets all of its I/O pins HIGH, preventing the Touch Display from booting its firmware, which is undesirable. The reason for the I/O pins being set HIGH is documented on <a href="http://www.atmel.com/Images/doc6120.pdf">page 5 of the ATMEL AT91SAM7X datasheet</a> which states that the pins on Parallel IO Controller A and B (PA0 - PA30 and PB0 - PB30) are pulled-up input at reset. The pins stay in that HIGH state until they're reconfigured by the Tiny CLR and the C# application itself. </li></ol><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B4%5D.gif"><img title="clip_image002" border="0" alt="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb%5B4%5D.gif" width="500" height="273"></a></p><p>For this reason, the custom shield is designed to control the power supply of the Touch Display module through a general-purpose <a href="http://www.onsemi.com/pub_link/Collateral/2N4403-D.PDF">2N4403</a> <a href="http://www.onsemi.com/pub_link/Collateral/2N4403-D.PDF">PNP transistor</a> (see T1_PNP on the shield schematics) connected to pin D7: it is only when the base of the transistor is asserted LOW that power flows to the Touch Display module, countering the behavior of the Netduino / Plus on boot. In addition, the Netduino / Plus controls the state of the Go! bus GPIO pin through D8, asserting it LOW before powering up the Touch Display module. </p><p>About the 2N4403 transistor: any other PNP transistor, or a <a href="http://www.electronics-tutorials.ws/transistor/tran_6.html">P-Channel MOSFET</a>, capable of switching at least 150mA continuously, the maximum current consumption of the touch display with some headroom, would have worked equally as well. The 2N4403 used here is more than adequate: </p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B8%5D-1.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B2%5D-4.png" width="356" height="337"></a> </p><p>In the context of this shield, the PNP transistor is used as a switch, either fully ON or OFF, as opposed to being used as an amplifier. To this end, a 1K ohm resistor is used between the base of the transistor and Netduino / Plus pin D7 (POWER_CTRL) to ensure that the transistor is fully saturated but also limiting the maximum current sunken through pin D7 and potential damage being done to the ATMEL chip. The 10K ohm pull-up resistor placed between the base of the transistor and the 3.3v power rail ensures that the transistor will always be turned off by default, even when pin D7 is floating (i.e. not specifically declared as an Input or as an Output and driven HIGH or LOW by the C# application). </p><p>The PowerUpDisplay function summarizes the interaction with the module through the shield on boot: </p><pre><pre class="brush: csharp">
// Pin connected to the transistor controlling the display's power supply
public static OutputPort PowerTransistor = new OutputPort(Pins.GPIO_PIN_D7, true);

public static void PowerUpDisplay() {
    // Ensure that the GPIO pin in low to prevent the display module to start in bootloader mode
    var goBusGPIO = new OutputPort(Pins.GPIO_PIN_D8, false);
    // Power up the display module
    PowerTransistor.Write(false);
    // Always wait 250ms after power-up to ensure that the display module is fully initialized before sending commands
    Thread.Sleep(250);
    goBusGPIO.Dispose();
}
</pre>

</pre><p><b></b></p><h5>Refactoring a Netduino Go! C# driver to work on a regular Netduino / Plus</h5><p>The final step to get the Touch Display module working outside of its natural environment involved refactoring its <a href="https://bitbucket.org/fabienroyer/nwazet.go/src/b24909aff18e/Library/Nwazet.Go.SDT028ATFTLCDTS/Nwazet.Go.SDT028ATFTLCDTS/Imaging/VirtualCanvas.cs">C# driver (VirtualCanvas.cs)</a>, eliminating the idiosyncrasies specific to Netduino Go! bus. <a href="http://www.netduino.com/downloads/">Go! modules are supposed to implement the <i>GoModule</i> interface as defined by the Netduino Go! SDK</a>. Because the regular Netduino / Plus SDK has no knowledge of this interface, it's necessary to strip out any references and API calls specific to the Go! framework, leaving only what's absolutely required to communicate with the Touch Display module over SPI and maintaining the disposable nature of the class. For more details on Go! SDK, please refer to <a href="http://forums.netduino.com/index.php?/forum/26-netduino-go/">the Netduino Go! community forums</a> and <a href="http://wiki.netduino.com/List-of-all-GO-Modules.ashx">the source code of the existing module drivers</a> as it is currently the best source of documentation. </p><p>This step is akin to the work required when adapting an Arduino library to run on the .Net Micro Framework, only in this case, the task is easier since we're dealing with a C# driver to begin with instead of going from C/C&#43;&#43; to C#. </p><p>Starting from the top of VirtualCanvas.cs, the following changes were made in the Netduino / Plus version of the driver: </p><ul><li>Removed <ul><li><i>using GoBus;</i> </li></ul></li><li>Replaced <ul><li><i>public class VirtualCanvas : GoModule</i> </li><li><i>with: public class VirtualCanvas : IDisposable</i> </li></ul></li><li>Replaced <ul><li><i>public void Initialize(GoSocket socket, uint speedKHz = 25000)</i> </li><li><i>with: public void Initialize(SPI.SPI_module displaySpi, Cpu.Pin displayChipSelect, Cpu.Pin displayGPIO, uint speedKHz = 25000). The core of the function simply initializes the SPI interface.</i> </li></ul></li><li>Replaced <ul><li><i>protected override void Dispose(bool disposing)</i> </li><li><i>with: public void Dispose() also removing the following calls:</i> <ul><li><i>SetSocketPowerState(false); this call is used by the GoModule object model to control when a socket is powered ON / OFF and is no longer applicable when the VirtualCanvas class is not derived from GoModule.</i> </li><li><i>base.Dispose(disposing); by the same token, deriving from GoModule requires overriding the behavior of the Dispose function and calling the base class at the end, something that is no longer needed now that the class implements the regular IDisposable interface.</i> </li></ul></li></ul></li><li>Moved <ul><li><i>GoBusIrqEvent.Reset(); from WaitUntilGoBusIrqIsAsserted()</i> </li><li><i>to: Execute(Synchronicity sync = Synchronicity.Synchronous) taking into account the higher latency of the Netduino / Plus</i> </li></ul></li></ul><p>The rest of the code remained unchanged. <a href="http://netduinohelpers.codeplex.com/">The Netduino / Plus Touch Display driver</a> and test application for this custom shield can be downloaded from the <a href="http://netduinohelpers.codeplex.com/">Netudino Helpers</a> project on CodePlex in the \Samples\Coding4Fun directory.</p><h4>Conclusion</h4><p>With nearly 300 known Arduino shields on the market, there's a wide variety of plug-and-play functionality waiting to be leveraged by the Netduino community, sometime with little or no software work required. When all else fails, building a shield from scratch to get a desired feature onto a Netduino / Plus is a relatively simple process only requiring reading component datasheets and some patience with a soldering iron or a small breadboard. In our next article, we'll put these guidelines to the test with a simple and popular off-the-shelf data logger shield made by Adafruit Industries. </p><h4>Appendix</h4><p>To build the shield interfacing with the [nwazet Touch Display, you will need the following parts: </p><blockquote><h5>Custom shield Eagle schematics</h5><ul><li><a href="https://bitbucket.org/fabienroyer/nwazet.channel9.articles/src/d33fe2c170e9/WhatIsAShield">Custom shield</a> </li></ul><h5>Bill of materials (~$15 for the shield w/o the [nwazet Touch Display module)</h5><ul><li>1 <a href="http://nwazet.com/touch-display-module">[nwazet Touch Display module</a> </li><li>1 <a href="http://nwazet.com/gocable10">10cm FCI connection cable</a> </li><li>1 <a href="https://www.adafruit.com/products/187">Adafruit DIY shield for Arduino</a> </li><li>1 <a href="http://www.proto-advantage.com/store/p/Netduino_GO_IDC_Adapter.php">ProtoAdvantage IDC Cable Breakout Board</a> </li><li>1 <a href="http://components.arrow.com/part/detail/40492237S7076394N5236">PNP Transistor 2N4403</a> </li><li>1 <a href="http://components.arrow.com/part/detail/39827066S7077451N5146">1K ohm resistor</a> </li><li>1 <a href="http://www.digikey.com/product-detail/en/CF14JT10K0/CF14JT10K0TR-ND/1741265?cur=USD">10K ohm resistor</a> </li><li>1 <a href="http://www.radioshack.com/product/index.jsp?productId=2049745">22 AWG solid core wire</a> </li><li>1 <a href="http://www.radioshack.com/product/index.jsp?productId=2062725">0.32&quot; diameter 60/40 rosin-core solder</a> </li></ul><h5>Eagle libraries</h5><ul><li><a href="http://www.ladyada.net/library/pcb/eaglelibrary.html">Adafruit Eagle library</a> (Netduino shield part) </li><li><a href="https://bitbucket.org/fabienroyer/nwazet.go/src">[nwazet Eagle library</a> (Go Socket part) </li></ul><h5>Netduino Go! Wiki</h5><ul><li><a href="http://wiki.netduino.com/Netduino-GO-Module-Builders-Guide.ashx">Netduino GO! Module Builder's Guide</a> (documents the Go! bus specifications) </li></ul></blockquote><h4>Bio</h4><p>Fabien is the Chief Hacker and co-founder of Nwazet, a start-up company located in Redmond WA, specializing in Open Source software and embedded hardware design. Fabien's passion for technology started 30 years ago, creating video games for fun and for profit. He went on working on mainframes, industrial manufacturing systems, mobile and web applications. Before Nwazet, Fabien worked at MSFT for eight years in Windows Core Security, Windows Core Networking and Xbox. During downtime, Fabien enjoys shooting zombies and watching sci-fi.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7615d43a7c264770886ca093015f17a6">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care</comments>
      <itunes:summary>C9 Netduino Shield Series - Using Arduino Shield with Netduino - Part I  &amp;nbsp;Photo courtesy of John Boxall  IntroductionWhen the Arduino Duemilanove microcontroller appeared in 2005, it featured a set of female pin headers exposing most of the pins of the ATmega168 for easy hacking and for connecting accessory boards known as &#39;Shields&#39;. The purpose of a shield is to provide new plug-and-play functionality to the host microcontroller, such as circuit prototyping, motion control, sensor integration, network and radio communication, or gaming interfaces, without worrying too much about the hardware implementation details. Seven years after the birth of the original Arduino, new shields keep coming out and are being cataloged on http://shieldlist.org/, a testament to the versatility of the design. It is also simple to build a DIY shield when nothing out there will meet your needs or when you want to understand how the shield concept works from the ground up.  In their infinite wisdom, Secret Labs, the makers of the Netduino, adopted the same Arduino form factor and header pin out to let .NET Micro Framework users tap into the vast array of Arduino shields on the market. Yet, there&#39;s always one hurdle that needs to be overcome: in order to give access to their hardware functions easily, many Arduino shields provide sample sketches (a.k.a. C/C&amp;#43;&amp;#43; Wiring programs) and libraries also written in C/C&amp;#43;&amp;#43; designed to be used within the Arduino IDE. Unfortunately, Arduino sketches and libraries aren&#39;t compatible with the Visual Studio environment and the .NET runtime: they need to be adapted in order to make use of the shield&#39;s hardware.  The goal of this series of articles is to attempt to demystify what an Arduino shield is. To do this, we&#39;ll start by building one from scratch. Then, we&#39;ll present a generic approach for selecting Netduino-compatible Arduino shields and adapting Arduino code to interface with the .NET Micro Framework.  Selecting Arduino shields </itunes:summary>
      <itunes:duration>119</itunes:duration>
      <link>http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care</link>
      <pubDate>Mon, 23 Jul 2012 05:30:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_512.jpg" height="287" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.mp3" expression="full" duration="119" fileSize="1910521" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.mp4" expression="full" duration="119" fileSize="11060612" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.webm" expression="full" duration="119" fileSize="4474071" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.wma" expression="full" duration="119" fileSize="975323" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.wmv" expression="full" duration="119" fileSize="13062199" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_high.mp4" expression="full" duration="119" fileSize="24485532" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_mid.mp4" expression="full" duration="119" fileSize="17151789" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_Source.wmv" expression="full" duration="119" fileSize="27616607" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.ism/manifest" expression="full" duration="119" fileSize="6076" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.wmv" length="13062199" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Fabien Royer</dc:creator>
      <itunes:author>Brian Peek, Fabien Royer</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Project Detroit, BoxingBots and Kinect at TechEd</title>
      <description><![CDATA[<p>The Coding4Fun team is packing up and heading to <a href="http://northamerica.msteched.com">TechEd North America</a> and <a href="http://europe.msteched.com/">Europe</a> this year, and we're bringing some of our toys along for the ride.&nbsp; We will also be giving a session on how to build Kinect applications with some great demos at both conferences.</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B11%5D-27.png" alt="image" width="220" height="100" align="left" border="0">At <a href="http://northamerica.msteched.com">TechEd North America</a> (June 11-14), you can stop by and check out the <a href="http://channel9.msdn.com/coding4fun/articles/Project-Detroit-An-Overview">Project Detroit Mustang</a>, or battle against another attendee with our <a href="http://channel9.msdn.com/coding4fun/projects/BoxingBots">BoxingBots</a>!</p><p>Project Detroit will be on the show floor Sunday through Wednesday.&nbsp; Stop by and get a picture of yourself in the driver's seat and try out all the features this car has to offer.</p><p><img src="http://files.channel9.msdn.com/thumbnail/09615539-1a33-49f7-b438-ca1b9543d712.jpg" alt="" width="640" height="363"></p><p>We will be running boxing matches with the BoxingBots on Monday night during the Welcome Reception, and Tuesday through Thursday around lunchtime.&nbsp; Battle against a fellow attendee after fueling up!</p><p><img src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0296%5B5%5D.jpg" alt="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/IMG_0296%5B5%5D.jpg" width="640" height="480"></p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/ae054c0b4d7b402ab1239e6800c0220f/image%5B16%5D-17.png" alt="image" width="181" height="109" align="left" border="0">If you're heading to <a href="http://europe.msteched.com/">TechEd Europe</a> (June 26-29), we will only have the BoxingBots with us.&nbsp; Apparently getting the car to Amsterdam is a bit tricky.&nbsp; Step up to battle another attendee on Tuesday night during the Welcome Reception, or Wednesday through Friday around lunchtime.</p><p>In addition, at both conferences, we will be giving a session on how to create fantastic Kinect applications for Windows, and we'll have some very fun demos to show. Here are the details:</p><blockquote><strong>Coding4Fun: Build Fun, Cool, Commercial Applications Using the Kinect for Windows SDK</strong><strong><br>Session Code:</strong> DEV330<br><br><p><strong>Speakers (North America):</strong> <a href="http://www.twitter.com/brianpeek">Brian Peek</a>, <a href="http://www.twitter.com/danielfe">Dan Fernandez</a><br><strong>Speakers (Europe):</strong> <a href="http://www.twitter.com/clintrutkas">Clint Rutkas</a>, <a href="http://www.twitter.com/danielfe">Dan Fernandez</a><br><br><strong>When (North America):</strong><em> Tuesday, June 12 at 5:00 PM - 6:15 PM in S320A<br></em><strong>When (Europe):</strong><em> Wednesday, June 27 at 5:00 PM - 6:15 PM</em></p><p>Come to this must-see session to find out how you can use the Kinect for Windows SDK to build commercial applications! Learn how the RGB and depth cameras work, how to use and fine-tune skeletal tracking, how to read an audio stream from the Kinect microphone array and even how to send Kinect data over the network including to your Windows Phone</p></blockquote><p>So, stop by, say hello, and have some fun with a couple of our projects.&nbsp; Hope to see you all there!</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:77cc494f90fa41c591c2a06700f222db">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/blog/Project-Detroit-and-BoxingBots-at-TechEd</comments>
      <itunes:summary>The Coding4Fun team is packing up and heading to TechEd North America and Europe this year, and we&#39;re bringing some of our toys along for the ride.&amp;nbsp; We will also be giving a session on how to build Kinect applications with some great demos at both conferences. At TechEd North America (June 11-14), you can stop by and check out the Project Detroit Mustang, or battle against another attendee with our BoxingBots! Project Detroit will be on the show floor Sunday through Wednesday.&amp;nbsp; Stop by and get a picture of yourself in the driver&#39;s seat and try out all the features this car has to offer.  We will be running boxing matches with the BoxingBots on Monday night during the Welcome Reception, and Tuesday through Thursday around lunchtime.&amp;nbsp; Battle against a fellow attendee after fueling up!  If you&#39;re heading to TechEd Europe (June 26-29), we will only have the BoxingBots with us.&amp;nbsp; Apparently getting the car to Amsterdam is a bit tricky.&amp;nbsp; Step up to battle another attendee on Tuesday night during the Welcome Reception, or Wednesday through Friday around lunchtime. In addition, at both conferences, we will be giving a session on how to create fantastic Kinect applications for Windows, and we&#39;ll have some very fun demos to show. Here are the details: Coding4Fun: Build Fun, Cool, Commercial Applications Using the Kinect for Windows SDKSession Code: DEV330Speakers (North America): Brian Peek, Dan FernandezSpeakers (Europe): Clint Rutkas, Dan FernandezWhen (North America): Tuesday, June 12 at 5:00 PM - 6:15 PM in S320AWhen (Europe): Wednesday, June 27 at 5:00 PM - 6:15 PM Come to this must-see session to find out how you can use the Kinect for Windows SDK to build commercial applications! Learn how the RGB and depth cameras work, how to use and fine-tune skeletal tracking, how to read an audio stream from the Kinect microphone array and even how to send Kinect data over the network including to your Windows Phone So, stop by, say hello, and have some fun</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/blog/Project-Detroit-and-BoxingBots-at-TechEd</link>
      <pubDate>Wed, 06 Jun 2012 18:01:07 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/blog/Project-Detroit-and-BoxingBots-at-TechEd</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/dbeac7ff-1385-4a5f-bb0a-2b884cde7fed.png" height="100" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/dd485edd-fda7-4ef8-9898-0fc6180572bc.png" height="220" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/7f653a1b-f3a9-4ab7-963b-d1d76ba39b7e.png" height="288" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek</dc:creator>
      <itunes:author>Brian Peek</itunes:author>
      <slash:comments>1</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/blog/Project-Detroit-and-BoxingBots-at-TechEd/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Project Detroit: Lighting System</title>
      <description><![CDATA[<p>In this article, we give a detailed look into the external lighting system of Project Detroit, the Microsoft-West Coast Custom Mustang creation. If you're not already familiar with this project, you can find more <a href="http://channel9.msdn.com/Blogs/Vector/The-400-horsepower-device">information here</a>.</p><h2>Overview</h2><p>The external lighting system for Project Detroit is run on a web server on a Netduino Plus, which uses the .NET Micro Framework (NETMF). To get an accelerated start, we leveraged code from the CodePlex project <a href="http://netduinohelpers.codeplex.com/">Netduino Helpers</a> to control the <a href="http://www.adafruit.com/products/306">AdaFruit LPD8806 LED</a> strip, and the <a href="http://forums.netduino.com/index.php?/topic/575-updated-web-server/">web server base code from the Netduino forums</a>. They have been tweaked slightly for our project.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/netduino%5B8%5D.jpg"><img title="netduino" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/netduino_thumb%5B3%5D.jpg" alt="netduino" width="500" height="375" border="0"></a></p><h2>Controllers, Routes, RESTful oh my!</h2><p>We wanted the NETMF web server to have the exact same routes as the full-blown REST service layer in Detroit. With compiler conditionals, this allowed the same code to use the same routes on both the full .NET stack and NETMF. Since we couldn't use the ASP.NET MVC framework here, we had to make something close to it.</p><h2>Controllers</h2><p>Controllers implement an interface with a method named <strong>ExecuteAction</strong>. When <strong>GetController</strong> is called, we return the correct controller but cast as the interface <strong>IController</strong>. This lets us figure out what controller should be executing the request and continue to work generically in the context of the request connection thread. If new functionality is needed, we create a new controller that inherits from IController&nbsp;and update GetController:</p><p><pre class="brush: csharp">
private static void RequestReceived(Request request)
{
    // url comes in as /foo/bar/12345?style=255
    //
     // /CONTROLLER/ACTION/
    //
    // LIGHTING SAMPLE URL: /0/1/?r=255&amp;g=255&amp;b=255&amp;zone=EnumAsInt
    // /0/... 0 = NetduinoControllerType.Lighting
    var validResponse = false;
    try
    {
        Logger.WriteLine(&quot;Start: &quot; &#43; request.Url &#43; &quot; at &quot; &#43; DateTime.Now);
        var urlInParts = request.Url.TrimStart(UriPathSeparator).Split(new[] {'?'}, 2);
        string[] uriSubParts = null;
        string[] queryStringSubParts = null;
        if (urlInParts.Length &gt; 0)
            uriSubParts = urlInParts[0].Split(UriPathSeparator);
                
        if (urlInParts.Length &gt; 1)
            queryStringSubParts = urlInParts[1].Split(QueryStringSeparator);
        if (uriSubParts != null &amp;&amp; uriSubParts.Length &gt; 1)
        {
            var targetController = GetController(uriSubParts[0]);
            if (targetController != null)
            {
                var action = (uriSubParts.Length &gt;= 2) ? uriSubParts[1] : string.Empty;
                var result = targetController.ExecuteAction(action, queryStringSubParts);
                validResponse = true;
                request.SendResponse(result.ToString());
                Logger.WriteLine(&quot;Result: &quot; &#43; result &#43; &quot; from &quot; &#43; request.Url &#43; &quot; at &quot; &#43; DateTime.Now);
            }
        }
        if (!validResponse)
        {
            SendIndexHtml(request);
        }
    }
    catch(Exception ex0)
    {
        Logger.WriteLine(ex0.ToString());
    }
}
</pre></p><h2>Routes, strings and enums on NETMF</h2><p>NETMF can't parse an enum from a string, which is something that can be done in the full .NET Framework. But what does this actually mean? It means the routes for the NETMF web server are a bit unreadable. Here is the same route but with the parsing issue exposed:</p><p><strong>Detroit's REST service route with ASP.NET MVC:</strong><br>http://…/Lighting/Solid/?zone=all&amp;r=255&amp;g=0&amp;b=0<br><br><strong>Detroit's NETMF route:<br></strong>http://…/0/3/?zone=0&amp;r=255&amp;g=0&amp;b=0</p><p>This issue made direct device debugging a bit harder.</p><h2>Parsing the Action and query string</h2><p>Parsing the route is broken into two parts. The first is determines what controller to target. For Project Detroit, that meant the lighting system or the rear glass system. Once we know the controller, we still need to parse the query string and action into something more useful:</p><p><pre class="brush: csharp">
#if NETMF
private static readonly char[] QueryStringParamSeparator = new[] { '=' };
public static LightingData ParseQueryStringValues(string action, params string[] queryStringParameters)
#else
public static LightingData ParseQueryStringValues(string action, Dictionary&lt;string, object&gt; queryStringParameters)
#endif
{
    var data = new LightingData {LightingZone = LightingZoneType.All, LightingAction = ParseLightingActionType(action)};
#if NETMF
    if (queryStringParameters != null)
    {
        foreach (var queryString in queryStringParameters)
        {
            var valueKey = queryString.Split(QueryStringParamSeparator);
            if (valueKey.Length != 2)
                continue;
            var key = valueKey[0];
            var value = valueKey[1];
#else
        foreach(var key in queryStringParameters.Keys)
        {
            var value = queryStringParameters[key].ToString();
#endif
            switch (key.ToLower())
            {
                case ZoneHuman:
                case ZoneComputer:
                    data.LightingZone = ParseLightingZoneType(value);
                    break;
                // more stuff
            }
        }
#if NETMF
    }
#endif
    // more stuff
            
    return data;
}
</pre></p><h2>Turning on the lights</h2><p>Individually addressable LED strips allow us to tell each individual LED what color to be. To adjust the colors of the LED lights, we loop through all the LEDs, set their color value, and then call <strong>LedRefresh()</strong> on our LED strip. There's no need to set all of them, only the ones being updated:</p><p><pre class="brush: csharp">
private static void SolidAnimationWorker()
{
    var leds = GetLedsToIlluminate();
    var dataCopy = _data;
    for (var i = 0; i &lt; leds.Length; i&#43;&#43;)
        SetLed(leds[i], dataCopy.Red, dataCopy.Green, dataCopy.Blue);
    LedRefresh();
}
</pre></p><h2>Zones / Animation Threads</h2><p>A solid color is boring, but we can use procedural animations to add some flair. The current code&nbsp;supports the following animations:</p><ul><li>Solid - A single solid color. </li><li>Fill - Goes from black to the desired color. The color stays lit. Much like filling a glass of liquid. <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /> </li><li>Random - LEDs are set to a random value. </li><li>Pulse - A glowing effect from bright to black. </li><li>Snake - A one way lighting effect with a fading tail that moves left to right. </li><li>Sweep - This effect was inspired by KITT and a Cylon robot and is similar to a snake pattern. The effect can also handle being split in two while maintaining a continual line for items such as the grill or the wheels. </li><li>Police - Each side flashes a red and blue light. </li></ul><p>Since we know the LED strip is a single strand, we can be clever with offsets and create groupings. By having a dedicated animation thread in each zone, we can have the grill of the car in Police Mode while the bottom fades to red and the vents fill to blue at different refresh rates.</p><p>To run an animation, we need to first kill the old animation thread, spin up a new thread, mark LEDs in the &quot;All LED&quot; zone as do not touch, and execute the new pattern. Without a way to mark the LEDs as &quot;bad&quot; in the &quot;All&quot; zone, the two animation threads would compete for setting the color and result in a flickering effect. Other zones don't have to worry about this since there is zero overlap of LEDs:&nbsp;</p><p><pre class="brush: csharp">
public bool ExecuteAction(string action, params string[] queryStringParameters)
{
    var data = LightingDataHelper.ParseQueryStringValues(action, queryStringParameters);
            
    SignalToEndAnimationThread(data.LightingZone);
    int counter = 0;
    while (counter&#43;&#43; &lt; 5 &amp;&amp; IsThreadAlive(data.LightingZone))
        Thread.Sleep(10);
    if (IsThreadAlive(data.LightingZone))
        AbortAnimationThread(data.LightingZone);
    // moving data bucket into public so new threads can leverage it
    _data = data;
    if (_data.LightingAction == LightingActionType.Police || _data.LightingAction == LightingActionType.Sweep)
    {
        _data.LightingZone = LightingZoneType.Grill;
        if (IsThreadAlive(_data.LightingZone))
            AbortAnimationThread(_data.LightingZone);
    }
    // cleaning up just incase
    if (data.LightingZone != LightingZoneType.All)
    {
        for (var i = 0; i &lt; _zoneAllAnimation.Length; i&#43;&#43;)
        {
            var leds = GetLedsToIlluminate();
            for (var z = 0; z &lt; leds.Length; z&#43;&#43;)
            {
                // flagging item as bad in animation lib
                if (_zoneAllAnimation[i] == leds[z])
                    _zoneAllAnimation[i] = -1;
            }
        }
    }
    switch (_data.LightingAction)
    {
        case LightingActionType.Solid:
            Debug.Print(&quot;Solid&quot;);
            ExecuteThread(SolidAnimationWorker);
            break;
        // more patterns
    }
    return true;
}
</pre></p><p>We can now do something more interesting, like Police Mode:</p><p><pre class="brush: csharp">
private static void PoliceModeAnimationWorker()
{
    var leds = GetLedsToIlluminate();
    var dataCopy = _data;
    var length = leds.Length;
    var half = length / 2;
    var index = 0;
    while (IsThreadSignaledToBeAlive(dataCopy.LightingZone))
    {
        int redIntensity = (index == 0) ? 255 : 0;
        int blueIntensity = (index == 0) ? 0 : 255;
        for (var i = 0; i &lt; half; i&#43;&#43;)
            SetLed(leds[i], redIntensity, 0, 0);
        for (var i = half; i &lt; length; i&#43;&#43;)
            SetLed(leds[i], 0, 0, blueIntensity);
        LedRefresh();
        index&#43;&#43;;
        index %= 2;
        Thread.Sleep(100);
    }
}
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/WP_000197%5B5%5D.jpg"><img title="WP_000197" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/WP_000197_thumb%5B2%5D.jpg" alt="WP_000197" width="500" height="375" border="0"></a></p><h2>Improvements</h2><p>Hindsight is 20/20. Nothing is ever perfect and there are of course items we'd love to change. At the start, the goal was to make this fairly generic and not Project Detroit &quot;aware.&quot; As you can see by looking at the source, that wasn't accomplished due to time constraints.</p><p>We would use a different LED system for two reasons: data transfer speed and power. The longer the LED strip is, the longer it takes to address an item further down the line. Project Detroit, having 15 meters of lighting in it, was impacted by this issue. It works well, just not as well as we hoped. The voltage requirements of the LEDs are another consideration. They are 5V, while a car uses 12V. Had we used 12V LEDs, our wiring would have been far simpler and wouldn't have required multiple transformers to get the required amperage needed at the correct voltage.</p><h2>Conclusion</h2><p>We think the lighting solution, coupled with the time and material constraints, worked out pretty well.&nbsp; Project Detroit was a ton of fun to build out and working with West Coast Customs was the chance of a lifetime.</p><p><img src="http://files.channel9.msdn.com/thumbnail/09615539-1a33-49f7-b438-ca1b9543d712.jpg" alt="" width="500" height="284"></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:f6bef172711342dbbca9a046016a6843">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-Lighting-System</comments>
      <itunes:summary>In this article, we give a detailed look into the external lighting system of Project Detroit, the Microsoft-West Coast Custom Mustang creation. If you&#39;re not already familiar with this project, you can find more information here. OverviewThe external lighting system for Project Detroit is run on a web server on a Netduino Plus, which uses the .NET Micro Framework (NETMF). To get an accelerated start, we leveraged code from the CodePlex project Netduino Helpers to control the AdaFruit LPD8806 LED strip, and the web server base code from the Netduino forums. They have been tweaked slightly for our project.  Controllers, Routes, RESTful oh my!We wanted the NETMF web server to have the exact same routes as the full-blown REST service layer in Detroit. With compiler conditionals, this allowed the same code to use the same routes on both the full .NET stack and NETMF. Since we couldn&#39;t use the ASP.NET MVC framework here, we had to make something close to it. ControllersControllers implement an interface with a method named ExecuteAction. When GetController is called, we return the correct controller but cast as the interface IController. This lets us figure out what controller should be executing the request and continue to work generically in the context of the request connection thread. If new functionality is needed, we create a new controller that inherits from IController&amp;nbsp;and update GetController: 
private static void RequestReceived(Request request)
{
    // url comes in as /foo/bar/12345?style=255
    //
     // /CONTROLLER/ACTION/
    //
    // LIGHTING SAMPLE URL: /0/1/?r=255&amp;amp;g=255&amp;amp;b=255&amp;amp;zone=EnumAsInt
    // /0/... 0 = NetduinoControllerType.Lighting
    var validResponse = false;
    try
    {
        Logger.WriteLine(&amp;quot;Start: &amp;quot; &amp;#43; request.Url &amp;#43; &amp;quot; at &amp;quot; &amp;#43; DateTime.Now);
        var urlInParts = request.Url.TrimStart(UriPathSeparator).Split(new[] {&#39;?&#39;}, 2);
        string[] uriSubParts = null;
       </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-Lighting-System</link>
      <pubDate>Mon, 21 May 2012 16:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Project-Detroit-Lighting-System</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/09c00fc4-d404-424d-8120-278d433390bd.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/6bff8dd9-2c4a-4fc0-9e5a-c03e80a68796.jpg" height="165" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/f7c84b3a-67a1-4580-aa9a-0554038a63bf.jpg" height="288" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-Lighting-System/RSS</wfw:commentRss>
      <category>NETMF</category>
      <category>Project Detroit</category>
    </item>
  <item>
      <title>Project Detroit: An Overview</title>
      <description><![CDATA[<p>In this article, we will give an overview of the technical side of Project Detroit, the Microsoft-West Coast Custom Mustang creation. If you're not already familiar with this project, you can find more <a href="http://channel9.msdn.com/Blogs/Vector/The-400-horsepower-device">information here</a>.&nbsp;</p><h2>Key Design Decisions</h2><p>It’s important to keep in mind that this car was built for a TV show with a set schedule. As a result, there are a number of unique design decisions that came into play.</p><p><img src="http://files.channel9.msdn.com/thumbnail/09615539-1a33-49f7-b438-ca1b9543d712.jpg" alt=""></p><p><strong>Schedule<br><br></strong>Working backwards, the reveal for the car was set for Monday November 28, 2011 at the Microsoft Store in Bellevue, Washington. We started the project in early August, which gave us approximately 12 weeks for research, development, vehicle assembly, and testing. This was by far the #1 design decision as any ideas or features for the car had to be implemented by the reveal date.</p><p><strong>Off the Shelf Parts<br><br></strong>Another key design decision was to, where possible, use off-the-shelf hardware and software in order to allow&nbsp; interested developers to build and reuse some of the subsystems for their own car (at least the ones that don’t require welding). For example, instead of buying pricey custom sized displays for the instrument cluster or passenger display, we used stock <a href="http://www.microsoftstore.com/store/msstore/pd/Samsung-Series-7-Slate/productID.241554200/vip.true">Samsung Series 7 Slate</a> PCs and had West Coast Customs do the hard work of building a custom dash to hold the PC.</p><p>&nbsp;</p><h2>Hardware and Networking</h2><p>The car is packed with a variety of computers and networking hardware.</p><ul><li><strong>Instrument Cluster Slate</strong> – This slate is on the driver's side and manages the instrument cluster application and the On-Board Diagnostic (OBD) connection to read telemetry data from the car. </li><li><strong>Passenger Slate – </strong>This slate, which is built into the passenger's side, runs a custom Windows 8 application (see Passenger slate below). <br><img title="USA_" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/Built-In_Touch_screen_Displays_Web_thumb%5B1%5D.jpg" alt="USA_" width="324" height="212" border="0"> </li><li><strong>Laptop 1 – </strong>This laptop runs the REST service to control different parts of the car, the Kinect socket service for the front Kinect, and the user message service to display messages on the rear glass while driving. </li><li><strong>Laptop 2 </strong>– This laptop runs the Heads Up Display (HUD) service, the Kinect socket service for the back Kinect, the OBD-II database, and Azure services. </li><li><strong>Windows Phone – </strong>A Nokia Lumia 800 connects via WiFi and a custom Windows Phone 7 application (See Windows Phone application below). </li><li><strong>Xbox 360 – </strong>The Xbox 360 displays on either the passenger HUD or the rear glass display. </li><li><strong>Networking</strong> – A <a href="http://www.netgear.com/home/products/wirelessrouters/high-performance/wndr3700.aspx">NETGEAR N600/WNDR3700</a> wireless router provides wired and wireless access for everything in the car, which is used in conjunction with a Verizon USB network card plugged into a <a href="http://www.cradlepoint.com/products/small-business-home-office-routers/mbr900-cellular-router">Cradle Point MBR900</a> to provide an always-on 3G/4G LTE internet connection. The slates, laptops, and Xbox 360 are connected via CAT5e cable, while the Windows Phone 7 connects via WiFi. </li></ul><p><strong>Note: </strong>One of the limitations of the Kinect SDK is that if you have multiple Kinects plugged into one PC, only one of those Kinects can do skeletal tracking at a time (color/depth data works just fine). Because of this, we decided to have a dedicated laptop plugged into the front Kinect and another laptop plugged into the back Kinect in order to allow front and back skeletal tracking at the same time. If we'd not used simultaneous skeletal tracking, we could have combined all of the systems onto a single laptop.</p><h2>Architecture</h2><p>Here is a quick overview of the application architecture.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/detroitArch%5B7%5D-1.png"><img title="detroitArch" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/detroitArch_thumb%5B4%5D.png" alt="detroitArch" width="500" height="319" border="0"></a></p><h2>&nbsp;</h2><h2>REST Service Layer</h2><p>The REST Service Layer allowed different systems talk to one another. More importantly, it allowed different services to control hardware they normally wouldn't be able to access.</p><ol><li><strong>Thin client approach<br></strong>The solution we chose was to have all the services that control different parts of the car reside on the laptops and have client applications like the Windows Phone application send REST commands to execute an action so the service layer would execute the request. <br><br></li><li><strong>REST-enable hardware</strong> <br>Controlling hardware should be invisible to the consuming clients. For example, hardware that requires USB communication would be impossible to control with a Windows Phone. The service layer allowed us to control hardware in a way that was invisible to the end user. <br><br></li><li><strong>Helper Libraries</strong><br>To simplify communication with the service layer, we built a set of helper classes to abstract out repetitive tasks like JSON serialization/deserialization, URI building, etc. For example, to get the list of car horn “ringtones”, the client application can call <strong>HornClient.List()</strong> to get back a list of available ringtone filenames. To set the car horn, the client calls <strong>HornClient.Set(filename)</strong>, and to play the car horn, it then calls <strong>HornClient.Play(filename)</strong>. The Helper libraries were built to work on Windows 7, Windows 8, and Windows Phone 7. </li></ol><h2>OBD-II</h2><p>We have already released an <a href="http://channel9.msdn.com/coding4fun/articles/Project-Detroit-How-to-Read-Your-Cars-Engine-Data-with-OBD-II">article</a> and <a href="http://obd.codeplex.com/">library</a> on the OBD-II portion of the car.&nbsp; In short, OBD-II stands for On-Board Diagnostics. Hooking into this port allows one to query for different types of data from the car, which we use to get the current speed, RPMs, fuel level, etc. for display in the Instrument Cluster and other locations. OBD can do far more than this, but it's all we needed for our project. Please see the linked articles for further details on the OBD-II library itself.</p><p>For the car, because only one application can open and communicate with a serial port at one time, we created a WCF service that polls the OBD-II data from the car and GPS data from a <a href="http://www.microsoftstore.com/store/msstore/en_US/pd/productID.216603800">Microsoft Streets &amp; Trips GPS locator</a>, and returns it to any application that queries the service.</p><p>For the OBD library, we used a manual connection to poll different values at different intervals. For values critical to driving the car—like RPM, speed, etc.—we polled for the values as quickly as the car could return them. With other values that weren’t critical to driving the car—like the fuel level, engine coolant temperature, etc.—we polled at a 1-2 second interval. For GPS, we subscribed to the <strong>LocationChanged</strong> event, which would fire when the GPS values changed.</p><p>Rather than creating a new serial port connection for every WCF request for OBD data, we created a singleton service that is instantiated when the service first runs. Accordingly, there is only one object in the WCF service that represents the last OBD and GPS data returned, which is obtained by the continual reading of the latest OBD data using the OBD library as described above. This means that calls to the WCF service <strong>ReadMeasurement</strong> method didn’t actually compute anything, but instead serialized the last saved data and returned it via the WCF service.</p><p>Since WCF supports multiple protocols, we implemented HTTP and TCP and ensured that any WCF service options we chose worked on Windows Phone, which, for example, can only use basic HTTP bindings.</p><p>To enable the ability to change the programming model later and to simplify the polling of the service, we built a helper library for Windows and Windows Phone that abstracts all the WCF calls.</p><p>The code below creates a new <strong>ObdService</strong> class and signs up for an event when the measurement has changed. The <strong>Start</strong> method does a couple of things: it lets you set the interval that you want to poll the <strong>ObdService</strong>, in this case every second (while the instrument cluster needs fast polling, the database logger can poll once a second). It also determines what IP address the service is hosted at (localhost), the protocol (HTTP or TCP), and whether to send “demo mode” data. Since one of the main ways the car is showcased is when it’s stopped on display, “demo mode” sends fake data, instead of always returning 0's for MPH, RPM, etc., so people can see what the instrument cluster would look like in action.</p><p><pre class="brush: csharp">
_service = new ObdService();
_service.ObdMeasurementChanged &#43;= service_ObdMeasurementChanged;
_service.Start(new TimeSpan(0, 0, 0, 0, 1000), localhost, Protocol.Http, false);

void service_ObdMeasurementChanged(object sender, ObdMeasurementChangedEventArgs e)
{
  Debug.Writeline(&quot;MPH=” &#43; e.Measurement.MilesPerHour);
}
</pre></p><h2>OBD-II Database &amp; Azure Services</h2><p>To record and capture the car telemetry data like MPH, RPM, engine load, and throttle (accelerator) position, as well as location data (latitude, longitude, altitude, and course), we used a SQL Server Express database with a simple, flat Entity Framework model, shown below. The primary key, the <strong>ObdMeasurementID</strong> is a GUID that is returned via the <strong>ObdService</strong>.&nbsp; Just like above, the database logger subscribes to the <strong>ObdMeasurementChanged</strong> event and receives a new reading at the time interval set in the <strong>Start()</strong> method.</p><p><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B7%5D-3.png" alt="image" width="319" height="522" border="0"></p><p>The Windows Azure data model uses Azure Table Services instead of SQL Server. The data mapping is essentially the same since both have a flat schema.</p><p>For Azure Table Storage, in addition to the schema above, you also need a partition key and a row key. For the partition key, we used a custom <strong>TripID</strong> (GUID) to represent a Trip. When the car is turned on/off a new TripID is created. That way we could group all measurements for that particular trip and do calculations based on that trip, like the average miles per gallon, distance traveled, fastest speed, etc. For the row key, we used a <strong>DateTimeOffset </strong>and a custom extension method, <strong>ToEndOfDays</strong>() that provides a unique numerical string (since Azure's row key is a string type) that subtracts the time from the <strong>DateTime.</strong><strong>Max</strong> value. The result is that the earlier a <strong>DateTime</strong> value, the larger the number.</p><p>Example:</p><p>Time=5/11/2012 9:14:09 AM, EndOfDays=2520655479509478223 //larger <br>Time=5/11/2012 9:14:11 AM, EndOfDays=2520655479482804811 //smaller</p><p>Since they are ordered in reverse order, with the most recent date/time being the first row, we can write an efficient query to pull just the first row to get the current latitude/longitude without needing to scan the entire table for the last measurment.</p><pre><br><pre class="brush: csharp">
public override string RowKey
{
    get
    {
        return new DateTimeOffset(TimeStamp).ToEndOfDays();
    }
    set
    {
        //do nothing
    }
}

public static class DateTimeExtensions
{
  public static string ToEndOfDays(this DateTimeOffset source)
  {  
    TimeSpan timeUntilTheEnd = DateTimeOffset.MaxValue.Subtract(source);
    return timeUntilTheEnd.Ticks.ToString();
  }

  public static DateTimeOffset FromEndOfDays(this String daysToEnd)
  {
    TimeSpan timeFromTheEnd = newTimeSpan(Int64.Parse(daysToEnd));
    DateTimeOffset source = DateTimeOffset.MaxValue.Date.Subtract(timeFromTheEnd);
    return source;
  }
}
</pre><br><br></pre><p>To upload data to Azure, we used a timer-based background uploader that would check to see if there was an internet connection, and then filter and upload all of the local SQL Express rows that had not been submitted to Azure using the <strong>Submitted </strong>boolean database field. On the Azure side, we used an ASP.NET MVC controller to submit data. The controller deserializes the data into a <strong>List&lt;MeasurementForTransfer&gt; </strong>type, it adds the data to a blob, and adds the blob to a queue as shown below.</p><p>A worker role (or many) will then read items off the queue and the new OBD measurement rows are placed into Azure Table Storage.</p><pre><br><pre class="brush: csharp">
public ActionResult PostData()
{
    try
    {
        StreamReader incomingData = new StreamReader(HttpContext.Request.InputStream);

        string data = incomingData.ReadToEnd();
        JavaScriptSerializer oSerializer =
            new JavaScriptSerializer();

        List&lt;MeasurementForTransfer&gt; measurements;
        measurements = oSerializer.Deserialize(data, typeof(List&lt;MeasurementForTransfer&gt;)) as List&lt;MeasurementForTransfer&gt;;

        if (measurements != null)
        {
            CloudBlob blob = _blob.UploadStringToIncoming(data);
            _queue.PushMessageToPostQueue(blob.Uri.ToString());
            return new HttpStatusCodeResult(200);
        }
        ...
    }
}
</pre><br><br></pre><h2>Instrument Cluster</h2><p>Much of this is also covered in our previously released OBD-II library where the instrument cluster application is included as a sample. This is a WPF application that runs on a Windows 7 slate. It contains three different skins designed by <a href="www.352media.com">352 Media</a>—a 2012 Mustang dashboard, a 1967 Mustang dashboard, and a Metro-style dashboard—each of which can be &quot;swiped&quot; through. This application queries the OBD-II WCF service described above as quickly as it can to retrieve speed, RPM, fuel level, and other data for display to the driver. The gauges are updated in real-time just as a real dashboard instrument cluster would behave.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/obd1%5B2%5D.png"><img title="obd1" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/obd1_thumb.png" alt="obd1" width="244" height="139" border="0"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/obd2%5B2%5D.png"><img title="obd2" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/obd2_thumb.png" alt="obd2" width="244" height="139" border="0"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/obd3%5B2%5D.png"><img title="obd3" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/obd3_thumb.png" alt="obd3" width="244" height="139" border="0"></a></p><h2>HUD</h2><p>The HUD (or Heads Up Display) application runs on one of the two Windows 7 computers in the car. This is a full-screen application that is output via a projector to a series of mirrors and a projection screen. This is then reflected onto the front glass of the windshield of the car. To install these, we altered the physical car's body and created brackets to mount mirrors and the projectors. In the picture on the left, you can see the dashboard's structural member pivoted outward. You can see the 12&quot; section we removed and added in the base plate to allow light to be reflected through to the windshield. <a href="http://twitter.com/wjsteele">Bill Steele </a>helped design and implement the physical HUD aspect into the car.</p><p><iFrame src="http://channel9.msdn.com/posts/Project-Detroit-Hud/player?w=512&amp;h=288" frameborder="0" scrolling="no" width="512px" height="288px"></iFrame></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/alterationFrame%5B2%5D.jpg"><img title="alterationFrame" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/alterationFrame_thumb.jpg" alt="alterationFrame" width="240" height="180" border="0"></a>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/mirrors%5B2%5D.jpg"><img title="mirrors" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/mirrors_thumb.jpg" alt="mirrors" width="240" height="180" border="0"></a></p><p>The HUD application has several different modes.&nbsp; The mode is selected from the Windows Phone application.</p><ul><li><strong>POI / Mapping</strong> – This uses <a href="http://msdn.microsoft.com/en-us/library/dd877180.aspx">Bing Maps services</a>. The phone or Windows 8 passenger application can choose one of a select group of categories (Eat, Entertain, Shop, Gas). Once selected, the REST service layer is contacted and the current choice is persisted. The HUD is constantly polling the service to know what the current category is, and when it changes, the HUD switches to an overhead map display with the closest locations of that category displayed, along with your always updated current GPS position and direction. The list of closest items in the category is requested every few seconds from the Bing Maps API and the map is updated appropriately. <br><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B10%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B6%5D-3.png" alt="image" width="324" height="204" border="0"></a> </li><li><strong>Car telemetry</strong> - In the car telemetry mode, the OBD data from the WCF service described above is queried and displayed on the screen.&nbsp; This can be though of as an overall car &quot;status&quot; display with the speed, RPMs, real-time MPG, time, and weather information. </li><li><strong>Weather</strong> – We use the <a href="http://www.worldweatheronline.com/">World Weather Online</a> API to get weather data for display on the HUD. This API allows queries for weather based on a latitude and longitude, which we have at all times. A quick call to the service gives us the current temperature and a general weather forecast, which we display as an icon next to the temperature in the lower-left portion of the screen. <strong><br><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-4.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B3%5D-5.png" alt="image" width="324" height="204" border="0"></a></strong> </li><li><strong>Kinect</strong> – Using our <a href="http://kinectservice.codeplex.com/">Kinect Service</a>, with the standard WPF client code, we can display the rear camera on the HUD to help the driver when backing up. See the Kinect Service project for more information on how this works and to use the service in an application of your own. </li></ul><h2>&nbsp;</h2><h2>Windows Phone Application</h2><p>One of the main ways to control the vehicle is through the Windows Phone application.&nbsp; <br><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a%5B4%5D.png"><img title="a" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a_thumb%5B2%5D.png" alt="a" width="196" height="324" border="0"></a></p><p>The first pivot of the app allows the user to lock, unlock, start the car, and set off the alarm.&nbsp; This is done through the <a href="http://www.viper.com">Viper</a> product from <a href="http://www.directed.com">Directed Electronics</a>.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a%5B8%5D.png"><img title="a" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a_thumb%5B4%5D.png" alt="a" width="196" height="324" border="0"></a></p><p>The second pivot contains the remaining ways that a user can interact with the car.</p><ul><li><strong>Kinect</strong> – This uses the Kinect service much in the way the HUD does. It can display both the front and rear cameras as well as allow the user to listen to an audio clip and send it up to the car while applying a voice changing effect.<br><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a%5B13%5D.png"><img title="a" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a_thumb%5B7%5D.png" alt="a" width="196" height="324" border="0"></a> </li><li><strong>Voice Effect</strong> – When the Talk button is pressed, the user can record their voice via the microphone. When released, the audio data is packaged in a simple WAV file and uploaded to the REST service. The user can select from several voice effects, such as Chipmunk and Deep. On the service side, that WAV file is modified with the selected effect and then played through the PA system. The code in this section of the app is very similar to the <a href="http://skypefx.codeplex.com/">Coding4Fun Skype Voice Changer</a>. We use <a href="http://naudio.codeplex.com/">NAudio</a> and several pre-made effects to process the WAV file for play. </li><li><strong>Lighting</strong> – This controls the external lighting for the car. The user can select a zone, an animation, and a color to apply. Once selected, this is communicated through the REST service to the lighting controller.<strong><br><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a%5B17%5D.png"><img title="a" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/a_thumb%5B9%5D.png" alt="a" width="404" height="244" border="0"></a></strong> </li><li><strong>Messaging</strong> – This presents a list of known pictures and videos for the user. The selection is sent to the car through the REST service and displayed on the projector that is pointed at the rear window, allowing following drivers to see the image, video, or message.&nbsp; </li><li><strong>Point Of Interest</strong> – As described earlier, this is the way the user can turn on the Point of Interest map on the HUD.&nbsp; Selecting one of the four items sends the selection to the REST service where it is persisted. The polling HUD will know when the selection is changed and display the map interface as shown above. </li><li><strong>Telemetry</strong> – This is a replica of the instrument cluster that runs on the Windows 7 slate. OBD data is queried via the WCF service, just like the slate, and displayed on the gauges, just like the slate.<br>&nbsp;<a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B13%5D-1.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B7%5D-2.png" alt="image" width="404" height="199" border="0"></a> </li><li><strong>Projection Screen</strong> – This will raise and lower the projection screen on the rear of the car. </li><li><strong>Horn</strong> – This displays a list of known horn sound effects that live on the REST service layer. Selecting any of the items will send a command through the REST to play that sound file on the external sound system of the car. This selected audio file would play when the horn was pressed in the car. </li><li><strong>Settings</strong> – Internal settings for setting up hardware and software for the car. </li></ul><h2>Passenger Application</h2><p>The passenger interface runs on a Samsung Series 7 slate running the Windows 8 Consumer Preview. This interface has a subset of the functionality provided by the Windows Phone application, but communicates through the same REST service. From this interface, the passenger can set the car horn sound effect, view the front and back Kinect cameras, select a Point of Interest category to be displayed on the HUD, and select the image, video or message that will be displayed on the rear window.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B14%5D-2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B8%5D-5.png" alt="image" width="324" height="204" border="0"></a></p><h2>External Car Lighting</h2><p>The external lighting system was controlled by a web server running on a <a href="http://netduino.com/netduinoplus/specs.htm">Netduino Plus</a> using a <a title="http://www.sparkfun.com/products/7914" href="http://www.sparkfun.com/products/7914">Sparkfun protoshield board</a> to simplify wiring, and allow for another shield to be used. The actual lights were <a href="http://www.adafruit.com/products/306">Digital Addressable RGB LED w/ PWM</a>. We'll also have a more in-depth article on this system on Coding4Fun shortly.</p><p>The car is broken down into different zones—grill, wheels, vents, etc. It also has a bunch of pre-defined procedural animation patterns that have a few adjustable parameters that allow for things like a snake effect, a sensor sweep, or even a police pattern. Each zone has its own thread which provides the ability to have multiple animation patterns going at the same time. When a command is received, the color, pattern, zone, and other data is then processed.</p><p>Here is a basic animation loop pattern.</p><p><pre class="brush: csharp">
private static void RandomAnimationWorker()
{
    var leds = GetLedsToIlluminate();
    var dataCopy = _data;
    var r = new Random();

    while (IsThreadSignaledToBeAlive(dataCopy.LightingZone))
    {
        for (var i = 0; i &lt; leds.Length; i&#43;&#43;)
            SetLed(leds[i], r.Next(255), r.Next(255), r.Next(255));

        LedRefresh();
        Thread.Sleep(dataCopy.TickDuration);
    }
}
</pre></p><h2>Rear Projection Window</h2><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/rearGlass%5B4%5D.jpg"><img title="rearGlass" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/rearGlass_thumb%5B2%5D.jpg" alt="rearGlass" width="480" height="360" border="0"></a></p><p>The rear projection system consists of <a href="http://www.trossenrobotics.com/store/p/5183-4-Inch-Stroke-110-LB-Linear-Actuator-with-Feedback.aspx">two 4” linear actuators</a>, <a href="http://www.trossenrobotics.com/store/p/5189-Dual-Linear-Actuator-Controller.aspx">a linear actual controller</a>, the NETMF web server from above, a <a href="http://www.seeedstudio.com/depot/relay-shield-p-693.html?cPath=132_134">Seeed Studio Relay Shield</a>, the back glass of a 1967 Ford Mustang, some <a href="http://www.ssidisplays.com/rear-projection-film/intrigue">rear projection film</a>, <a href="http://www.amazon.com/Casio-Green-Projector-Lumens-XJ-A250/sim/B004I36R6Q/2">a low profile yet insanely bright projector that accepts serial port commands</a>, and a standard USB to serial adapter.</p><p>The REST service layer toggles the input of the projector based on the selected state.&nbsp; This would allow us to go from the HDMI output of an Xbox 360 to the VGA output of the laptop.&nbsp; While doing this, the REST layer sends a command to the NETMF web server to either raise or lower the actuators.</p><p>Here is the code for the NETMF to control the raising and lowering the glass:</p><p><pre class="brush: csharp">
public static class Relay
{
    // code for for Electronic Brick Relay Shield
    static readonly OutputPort RaisePort = new OutputPort(Pins.GPIO_PIN_D5, false);
    static readonly OutputPort LowerPort = new OutputPort(Pins.GPIO_PIN_D4, false);

    const int OpenCloseDelay = 1000;

    public static bool Raise()
    {
        return ExecuteRelay(RaisePort);
    }

    public static bool Lower()
    {
        return ExecuteRelay(LowerPort);
    }

    private static bool ExecuteRelay(OutputPort port)
    {
        port.Write(true);
        Thread.Sleep(OpenCloseDelay);
        port.Write(false);

        return true;
    }
}
</pre></p><h2>Messaging System</h2><p>This is a WPF application that leveraged the file system on the computer to communicate between the REST service layer and itself.&nbsp; Visually, it shows the message/image/video in the rear view mirror but it actually does two other tasks, it operates our car horn system and plays the recorded audio output from the phone.</p><ul><li><strong>Displaying Messages</strong><br>To display images, we poll the REST service every second for an update.&nbsp; Depending on the return type, we either display a TextBlock element or a MediaElement.<br><br></li><li><strong>Detecting and Playing Car Horn</strong><br>When someone presses the horn in the car, it is detected by a Phidget 8/8/8 wired into a Digital Input. In-between the car horn and the Phidget, there is a relay as well. This isolates the voltage coming from the horn and solves a grounding issue. We then feed back two wires from that relay and put one into the ground and the other into one of the digital inputs. In the application, we listen to the <strong>InputChange</strong> event on the Phidget and play / stop the audio based on the state.<br><br></li><li><strong>Detecting new recorded audio from the phone and car horn changes</strong><br>When someone talks into the phone or selects a new car horn, the REST service layer places that audio file into a predetermined directory. The Messaging service then uses a <strong>FileSystemWatcher</strong> to detect when this file is added. The difference between the car horn detection and recorded audio is the recorded audio will play once it is done writing to the file system. </li></ul><h2>External PA System</h2><p>To interact with people, we installed an external audio PA or Public Address system. This system is hooked into the laptop that is connected to the car horn, and can play audio data from the phone. Having a PA system that is as simple as an audio jack that plugs into a PC enabled us to have different ringtones for the car horn and to talk through the car using Windows Phone.</p><h2>Conclusion</h2><p>After months of planning and building, the Project Detroit car was shown to the world on an episode of Inside West Coast Customs. Though it was a ton of work, the end product is something we are all proud of. We hope that this project inspires other developers to think outside the box and realize what can be done with some off-the-shelf hardware, software, and passion.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/splash%5B5%5D.jpg"><img title="splash" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/splash_thumb%5B3%5D.jpg" alt="splash" width="480" height="350" border="0"></a></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1a2766655d5e40eb9dbea030013669f1">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-An-Overview</comments>
      <itunes:summary>In this article, we will give an overview of the technical side of Project Detroit, the Microsoft-West Coast Custom Mustang creation. If you&#39;re not already familiar with this project, you can find more information here.&amp;nbsp; Key Design DecisionsIt’s important to keep in mind that this car was built for a TV show with a set schedule. As a result, there are a number of unique design decisions that came into play.  ScheduleWorking backwards, the reveal for the car was set for Monday November 28, 2011 at the Microsoft Store in Bellevue, Washington. We started the project in early August, which gave us approximately 12 weeks for research, development, vehicle assembly, and testing. This was by far the #1 design decision as any ideas or features for the car had to be implemented by the reveal date. Off the Shelf PartsAnother key design decision was to, where possible, use off-the-shelf hardware and software in order to allow&amp;nbsp; interested developers to build and reuse some of the subsystems for their own car (at least the ones that don’t require welding). For example, instead of buying pricey custom sized displays for the instrument cluster or passenger display, we used stock Samsung Series 7 Slate PCs and had West Coast Customs do the hard work of building a custom dash to hold the PC. &amp;nbsp; Hardware and NetworkingThe car is packed with a variety of computers and networking hardware. Instrument Cluster Slate – This slate is on the driver&#39;s side and manages the instrument cluster application and the On-Board Diagnostic (OBD) connection to read telemetry data from the car. Passenger Slate – This slate, which is built into the passenger&#39;s side, runs a custom Windows 8 application (see Passenger slate below).  Laptop 1 – This laptop runs the REST service to control different parts of the car, the Kinect socket service for the front Kinect, and the user message service to display messages on the rear glass while driving. Laptop 2 – This laptop runs the Heads Up Display (</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-An-Overview</link>
      <pubDate>Mon, 14 May 2012 16:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Project-Detroit-An-Overview</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/9c7747e3-41c9-419a-a59f-3a5b6c011ff4.jpg" height="57" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/9ac4b4d9-a9d6-42d9-888e-12638265be2c.jpg" height="125" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/285e8cb8-688c-4867-9523-40d0e1f3d9d2.jpg" height="291" width="512"></media:thumbnail>      
      <dc:creator>Brian Peek, Clint Rutkas, Dan Fernandez</dc:creator>
      <itunes:author>Brian Peek, Clint Rutkas, Dan Fernandez</itunes:author>
      <slash:comments>11</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-An-Overview/RSS</wfw:commentRss>
      <category>Project Detroit</category>
    </item>
  <item>
      <title>Project Detroit: How to Read Your Car’s Engine Data with OBD-II</title>
      <description><![CDATA[<p>In this article we will look at the OBD-II sub-system and instrument cluster application of the Project Detroit Mustang we built with West Coast Customs.&nbsp; If you're not familiar with this project, you can find out more about it <a href="http://channel9.msdn.com/coding4fun/detroit">here</a> and <a href="http://channel9.msdn.com/Blogs/Vector/The-400-horsepower-device">here</a>.</p><h2>OBD-II</h2><p>OBD stands for On-Board Diagnostics.&nbsp; In the world of cars, this can be thought of as the computer which has a variety of data points which can be queried, such as speed, fuel level, and even trouble codes that relate to the check engine light.&nbsp; If you've ever taken your car in for service, your service center has hooked up the car to a computer via the OBD port to get the status of the car and what may not be working properly.</p><h2>Getting Started</h2><p>To use the OBD library with your vehicle, first you need an OBD to USB or serial cable.&nbsp; These can be found in numerous places, but we recommend <a href="http://www.scantool.net/scan-tools/pc-based/obdlink-sx.html">this cable from ScanTool.net</a>, which was used with the <a href="http://channel9.msdn.com/coding4fun/detroit">Project Detroit</a> car and our software.&nbsp; Here's how to get connected:</p><ol><li>With the car off, plug the OBD end into your vehicle.&nbsp; The port is in a different location in every vehicle, but it's guaranteed to be somewhere near the driver's location. <a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_05456.jpg"><img title="IMG_0545" border="0" alt="IMG_0545" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/IMG_0545_thumb3.jpg" width="444" height="219"></a> </li><li>Plug the USB/serial end of the cable into your computer and note which COM port the cable is connected to. </li><li>Update the <strong>app.config</strong> file of the <strong>InstrumentCluster</strong> project with that COM port. </li><li>Start the car. </li><li>Run the <strong>InstrumentCluster</strong> application, and data should start flowing. </li></ol><h2>Calling the OBD library programmatically</h2><ul><li>Create an instance of the <strong>ObdDevice</strong> class </li><li>Call the <strong>Connect</strong> method with the appropriate COM port, baud rate, and, if known, OBD protocol </li><li>From here, the library works in two ways: automatic polling or manual polling <ul><li><strong>Automatic</strong> – Pass <strong>true</strong> to the <strong>Connect</strong> method. This will poll the OBD as quickly as it can requesting RPM, MPH, MPG, Fuel Level and Engine Coolant Temperature. Note that not all vehicles will support all of these. In this mode, hook the <strong>ObdChanged</strong> event to receive an <strong>ObdState</strong> packet with the new data. </li><li><strong>Manual</strong> – Pass <strong>false</strong> to the <strong>Connect</strong> method. Then, create your own thread and call the <strong>ObdDevice</strong>'s Get methods to retrieve the data you want as quickly as you want it.&nbsp; This is the way we used the library in Project Detroit.&nbsp; We polled manually, collecting the speed, RPM, and other critical data as quickly as possible, while only reading things like fuel level every few seconds. </li></ul></li></ul><p><br>OBD is a polled system, so data can only be returned as quickly as the time it takes to request it and return it. In short, only retrieve what you need when you need it.</p><p><pre class="brush: csharp">
ObdDevice obd;

obd = new ObdDevice();
obd.ObdChanged &#43;= _obd_ObdChanged;

// com port, baud rate, protocol (if known), automatic polling
obd.Connect(&quot;COM1&quot;, 115200, ObdDevice.UnknownProtocol, true);

...

void obd_ObdChanged(object sender, ObdChangedEventArgs e)
{
    e.ObdState.ToString();
}
</pre></p><h2>Customizing the Instrument Cluster</h2><p>The Instrument Cluster application is a WPF application that has 3 different skins which can be viewed by swiping left or right in the application, either with a finger, or the mouse.&nbsp; This is a simplified version of the actual application we used in the Project Detroit car, modified to talk straight to the OBD port instead of our intermediate WCF service.&nbsp; Please note that this isn't a robust, drop-in replacement application for a car dashboard, but only a sample of how the OBD library can be used.</p><p>Internally, the application uses the OBD library and hooks the <strong>ObdChanged</strong> event.&nbsp; The <strong>ObdChanged</strong> event returns a minimal amount of important data.&nbsp; When the event fires, the the <strong>SetInstrumentClusterValues</strong> method is run, which sets the OBD values to each gauge in whichever skin is currently visible.</p><p><pre class="brush: csharp">
private void SetInstrumentClusterValues(ObdState measurement)
{
    foreach (var item in _skins)
    {
        if(!item.IsVisible)
            continue;
        item.IsMalfunctionVisible = measurement.MilLightOn;
        item.IsLowFuelVisible = item.Fuel &lt; 10;
        item.MPG = measurement.MilesPerGallon;
        item.MPH = measurement.MilesPerHour;
        item.RPM = measurement.Rpm;
        item.Fuel = measurement.FuelLevel;
        item.Temperature = measurement.EngineCoolantTemperature;
    }
}
</pre></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/Download3.png"><img title="Download" border="0" alt="Download" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/Download_thumb1.png" width="644" height="364"></a></p><h2>More Information</h2><ul><li><a href="http://channel9.msdn.com/coding4fun/detroit">Project Detroit</a> </li><li><a href="http://en.wikipedia.org/wiki/OBD-II#OBD-II">More information on OBD-II</a> </li><li><a href="http://elmelectronics.com/DSheets/ELM327DS.pdf">ELM323/327 Datasheet</a> </li><li><a href="http://www.scantool.net/scan-tools/pc-based/obdlink-sx.html">OBD-II to USB cable</a> </li></ul><h2>Known Issues / Limitations</h2><ul><li>This is known to work with cables that uses the ELM323/327 chipset. The specific cable that was used to develop this library is available from <a href="http://www.scantool.net/scan-tools/pc-based/obdlink-sx.html">ScanTool.net</a>, however other ELM323/327 OBD-II to USB cables should work. </li><li>There are a variety of different <a href="http://en.wikipedia.org/wiki/On-board_diagnostics#OBD-II_Signal_Protocols">OBD-II signal protocols</a>. This library only supports a few of them. If your car's OBD protocol is not supported, please feel free to add it and send us the changes to integrate back into the library! </li><li>If the vehicle has multiple ECUs, the ECU with the most PIDs is used. The other ECUs are ignored. </li><li>Not every standard PID is supported. </li><li>No custom manufacturer/model-specific PIDs are supported. </li></ul> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/BrianPeek/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:f307abe7cf074cacb336a02e012fba25">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-How-to-Read-Your-Cars-Engine-Data-with-OBD-II</comments>
      <itunes:summary>In this article we will look at the OBD-II sub-system and instrument cluster application of the Project Detroit Mustang we built with West Coast Customs.&amp;nbsp; If you&#39;re not familiar with this project, you can find out more about it here and here. OBD-IIOBD stands for On-Board Diagnostics.&amp;nbsp; In the world of cars, this can be thought of as the computer which has a variety of data points which can be queried, such as speed, fuel level, and even trouble codes that relate to the check engine light.&amp;nbsp; If you&#39;ve ever taken your car in for service, your service center has hooked up the car to a computer via the OBD port to get the status of the car and what may not be working properly. Getting StartedTo use the OBD library with your vehicle, first you need an OBD to USB or serial cable.&amp;nbsp; These can be found in numerous places, but we recommend this cable from ScanTool.net, which was used with the Project Detroit car and our software.&amp;nbsp; Here&#39;s how to get connected: With the car off, plug the OBD end into your vehicle.&amp;nbsp; The port is in a different location in every vehicle, but it&#39;s guaranteed to be somewhere near the driver&#39;s location.  Plug the USB/serial end of the cable into your computer and note which COM port the cable is connected to. Update the app.config file of the InstrumentCluster project with that COM port. Start the car. Run the InstrumentCluster application, and data should start flowing. Calling the OBD library programmaticallyCreate an instance of the ObdDevice class Call the Connect method with the appropriate COM port, baud rate, and, if known, OBD protocol From here, the library works in two ways: automatic polling or manual polling Automatic – Pass true to the Connect method. This will poll the OBD as quickly as it can requesting RPM, MPH, MPG, Fuel Level and Engine Coolant Temperature. Note that not all vehicles will support all of these. In this mode, hook the ObdChanged event to receive an ObdState packet with the new data. Manual</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-How-to-Read-Your-Cars-Engine-Data-with-OBD-II</link>
      <pubDate>Mon, 09 Apr 2012 19:24:20 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Project-Detroit-How-to-Read-Your-Cars-Engine-Data-with-OBD-II</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/22cf6572-42c8-47ed-a95b-1b8b2bbe200a.png" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/2a2ec08a-7d5d-458d-b1f6-fa8fb2ebce1d.png" height="124" width="220"></media:thumbnail>      
      <dc:creator>Brian Peek, Dan Fernandez</dc:creator>
      <itunes:author>Brian Peek, Dan Fernandez</itunes:author>
      <slash:comments>19</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Project-Detroit-How-to-Read-Your-Cars-Engine-Data-with-OBD-II/RSS</wfw:commentRss>
      <category>Coding4Fun</category>
      <category>Hardware</category>
      <category>Project Detroit</category>
    </item>    
</channel>
</rss>